lib/sarah.rb in sarah-2.0.1 vs lib/sarah.rb in sarah-2.1.0
- old
+ new
@@ -40,31 +40,33 @@
#
# = Internal Structure
#
# As of version 2.0.0, there are three major data structures internally:
# * "seq" - an array of sequentially-indexed values beginning at index 0
-# (except when negative actual keys are present; see {#negative_mode=}
+# (except when negative actual keys are present; see {#negative_mode}
# :actual)
# * "spr" - a hash representing a sparse array of all other
# numerically-indexed values
# * "rnd" - a "random access" hash of all non-numerically keyed values
#
# The sequential and sparse parts are collectively referred to as "ary".
-# All three parts together are collectively referred to as "all".
+# In some contexts, the non-sequential (sparse and random) parts are
+# available as "nsq". All three parts together are collectively referred
+# to as "all".
#
# Some methods allow you to direct their action to all or specific parts
# of the structure by specifying a corrsponding symbol, :seq, :spr, :ary,
-# :rnd, or :all.
+# :nsq, :rnd, or :all.
#
# @author Brian Katzung (briank@kappacs.com), Kappa Computer Solutions, LLC
# @copyright 2013-2014 Brian Katzung and Kappa Computer Solutions, LLC
# @license MIT License
-# @version 2.0.0
+# @version 2.1.0
class Sarah
- VERSION = "2.0.0"
+ VERSION = "2.1.0"
# Private attributes:
# seq [Array] An array of (zero-origin) sequential values.
# spr [Hash] A hash of (typically sparse) integer-keyed values. If
# there are any negatively-keyed values (in :actual negative mode),
@@ -85,12 +87,19 @@
# @return [Proc|nil]
attr :default_proc
# @!attribute [r] negative_mode
# @return [:actual|:error|:ignore]
- # How negative indexes/keys are handled. Possible values are
- # :actual, :error, and :ignore. See {#negative_mode=}.
+ # How negative indexes/keys are handled.
+ #
+ # :actual - Negative keys represent themselves and are not treated
+ # specially (although delete works like unset in this mode--values
+ # are not reindexed)
+ # :error (default) - Negative keys are interpreted relative to the
+ # end of the array; keys < -@ary_next raise an IndexError
+ # :ignore - Like :error, but keys < -@ary_next are treated as
+ # non-existent on fetch and silently ignored on set
attr_reader :negative_mode
# ##### Class Methods #####
# Instantiate a "Sarah literal".
@@ -407,10 +416,12 @@
# #combination is not implemented.
# Remove nil values in place. In the case of the sequential and sparse
# arrays, the remaining values are reindexed sequentially from 0.
#
+ # See also {#reindex}.
+ #
# @param which [:all|:ary|:rnd] Which data structures are compacted.
# @return [Sarah]
def compact! (which = :all)
case which when :all, :ary
@seq = values(:ary).compact
@@ -478,11 +489,11 @@
alias_method :delete_key, :delete_at
# Deletes each value for which the required block returns true.
#
- # Subsequent values are re-indexed except when {#negative_mode=}
+ # Subsequent values are re-indexed except when {#negative_mode}
# :actual. See also {#unset_if}.
#
# The block is passed the current value and nil for the sequential
# and sparse arrays or the current value and key (in that order)
# for the random-access hash.
@@ -515,12 +526,12 @@
self
end
# Delete by value.
#
- # Subsequent values are re-indexed except when {#negative_mode=} :actual.
- # See also {#unset_value}.
+ # Subsequent values are re-indexed except when {#negative_mode} is
+ # :actual. See also {#unset_value}.
#
# @param what [Object] The value to be deleted
# @param which [:all|:ary|:rnd] The data structures in which to delete.
# @return [Sarah]
def delete_value (what, which = :all)
@@ -749,29 +760,34 @@
nil
end
# Return the random-access hash keys.
#
+ # Since 2.0.0 returns only the random-access keys. Since 2.1.0
+ # returns the non-sequential (sparse + random) keys like the
+ # pre-2.0.0 version.
+ #
# @return [Array]
- # @deprecated Please use {#keys} instead.
- def rnd_keys; @rnd.keys; end
+ # @deprecated Please use {#keys} :nsq or #keys :rnd instead.
+ def rnd_keys; self.keys :nsq; end
# Return the sequential array keys (indexes).
#
# @return [Array<Integer>]
- # @deprecated Please use {#keys} instead.
- def seq_keys; 0...@seq.size; end
+ # @deprecated Please use {#keys} :seq instead.
+ def seq_keys; self.keys :seq; end
# Return an array of indexes and keys.
#
- # @param which [:all|:ary|:rnd|:seq|:spr] Which indexes and keys
- # to return. (Since 2.0.0)
+ # @param which [:all|:ary|:nsq|:rnd|:seq|:spr] Which indexes and keys
+ # to return. (Since 2.0.0; :nsq since 2.1.0)
# @return [Array]
def keys (which = :all)
case which
when :all then keys(:seq) + keys(:spr) + @rnd.keys
when :ary then keys(:seq) + keys(:spr)
+ when :nsq then keys(:spr) + @rnd.keys
when :rnd then @rnd.keys
when :seq then (0...@seq.size).to_a
when :spr then @spr.keys.sort
else []
end
@@ -785,34 +801,38 @@
# @return [Object|Array]
def last (*args); values(:ary).last(*args); end
# Return the random-access hash size.
#
- # @deprecated Please use {#size} instead.
+ # Since 2.1.0, this returns the non-sequential (sparse + random)
+ # hash size, which is more closely reflects the pre-2.0.0 value.
+ #
+ # @deprecated Please use {#size} :rnd or #size :nsq instead.
# @return [Integer]
- def rnd_length; @rnd.size; end
+ def rnd_length; self.size :nsq; end
alias_method :rnd_size, :rnd_length
# Return the sequential array size.
#
- # @deprecated Please use {#size} instead.
+ # @deprecated Please use {#size} :seq instead.
# @return [Integer]
def seq_length; @seq.size; end
alias_method :seq_size, :seq_length
# Return the number of stored values (AKA size or length).
#
- # @param which [:all|:ary|:rnd|:seq|:spr] The data structures
- # for which the (combined) size is to be returned. (Since 2.0.0)
+ # @param which [:all|:ary|:nsq|:rnd|:seq|:spr] The data structures
+ # for which the (combined) size is to be returned. (Since 2.0.0;
+ # :nsq since 2.1.0)
# @return [Integer]
def length (which = :all)
size = 0
case which when :all, :ary, :seq then size += @seq.size end
- case which when :all, :ary, :spr then size += @spr.size end
- case which when :all, :rnd then size += @rnd.size end
+ case which when :all, :ary, :nsq, :spr then size += @spr.size end
+ case which when :all, :nsq, :rnd then size += @rnd.size end
size
end
alias_method :size, :length
@@ -833,18 +853,10 @@
alias_method :update, :merge!
# Sets the negative mode, the manner in which negative integer
# index/key values are handled.
- #
- # :actual - Negative keys represent themselves and are not treated
- # specially (although delete works like unset in this mode--values
- # are not reindexed)
- # :error (default) - Negative keys are interpreted relative to the
- # end of the array; keys < -@ary_next raise an IndexError
- # :ignore - Like :error, but keys < -@ary_next are treated as
- # non-existent on fetch and silently ignored on set
def negative_mode= (mode)
case mode
when :actual then @negative_mode = :actual
when :error, :ignore
# These modes are only possible if there aren't currently
@@ -907,10 +919,26 @@
#
# @return [Sarah]
# @since 2.0.0
def rehash; @spr.rehash; @rnd.rehash; self; end
+ # Reindex sparse array values sequentially after any existing
+ # sequential values (or else from index 0).
+ #
+ # This is an immediate in-place operation (not a mode) and is unaffected
+ # by the {#negative_mode}.
+ #
+ # @return [Sarah]
+ # @since 2.1.0
+ def reindex
+ if !@spr.empty?
+ @seq.concat values(:spr)
+ @spr, @ary_first, @ary_next = {}, 0, @seq.size
+ end
+ self
+ end
+
# #repeated_combination is not implemented.
# #repeated_permutation is not implemented.
# Replace contents with the contents of another array, hash, or Sarah.
@@ -978,23 +1006,26 @@
end
return @seq.rindex(value)
end
end
- # Return the sparse array and random-access hash (for
+ # Return a copy of the merged sparse array and random-access hash (for
# backward-compatibility only).
#
+ # Through version 2.0.0, this returned the actual underlying random-access
+ # hash.
+ #
# @return [Hash]
- # @deprecated Please use {#to_h} instead.
- def rnd; @rnd; end
+ # @deprecated Please use {#to_h} :nsq instead.
+ def rnd; self.to_h :nsq; end
# Return the sparse array and random-access hash values (for
# backward-compatibility only).
#
# @return [Array]
- # @deprecated Please use {#values} instead.
- def rnd_values; @spr.values + @rnd.values; end
+ # @deprecated Please use {#values} :nsq or #values :rnd instead.
+ def rnd_values; self.values :nsq; end
# Rotate sequential and sparse array values into a sequential list.
#
# @param count [Integer] The amount to rotate. See Array#rotate!.
# @return [Sarah]
@@ -1021,13 +1052,15 @@
to_h(which).select { |key, value| yield key, value }
end
# Return a copy of the sequential array values.
#
+ # Prior to 2.0.0, this returned the actual underlying array.
+ #
# @return [Array]
- # @deprecated Please use {#values} instead.
- def seq; Array.new(@seq); end
+ # @deprecated Please use {#values} :seq instead.
+ def seq; self.values :seq; end
alias_method :seq_values, :seq
# Set values and/or key/value pairs (in standard Ruby calling syntax).
#
@@ -1200,31 +1233,33 @@
# #take_while is not implemented.
# Return all or part of the structure in array representation.
#
- # @param which [:all|:ary|:rnd|:seq|:spr] The parts to represent.
+ # @param which [:all|:ary|:nsq|:rnd|:seq|:spr] The parts to represent.
+ # (:nsq since 2.1.0)
# @since 2.0.0
def to_a (which = :all)
ary, hsh = [], {}
case which when :all, :ary, :seq then ary = @seq end
- case which when :all, :ary, :spr then hsh.merge! @spr end
- case which when :all, :rnd then hsh.merge! @rnd end
+ case which when :all, :ary, :nsq, :spr then hsh.merge! @spr end
+ case which when :all, :nsq, :rnd then hsh.merge! @rnd end
ary + [hsh]
end
# Return all or part of the structure in hash representation.
#
- # @param which [:all|:ary|:rnd|:seq|:spr] The parts to represent.
+ # @param which [:all|:ary|:nsq|:rnd|:seq|:spr] The parts to represent.
+ # (:nsq since 2.1.0)
# @since 2.0.0
def to_h (which = :all)
hsh = {}
case which when :all, :ary, :seq
@seq.each_index { |i| hsh[i] = @seq[i] }
end
- case which when :all, :ary, :spr then hsh.merge! @spr end
- case which when :all, :rnd then hsh.merge! @rnd end
+ case which when :all, :ary, :nsq, :spr then hsh.merge! @spr end
+ case which when :all, :nsq, :rnd then hsh.merge! @rnd end
hsh
end
# #transpose is not implemented.
@@ -1344,16 +1379,17 @@
self
end
# Return an array of values.
#
- # @param which [:all|:ary|:rnd|:seq|:spr] Which values to return.
- # (Since 2.0.0)
+ # @param which [:all|:ary|:nsq|:rnd|:seq|:spr] Which values to return.
+ # (Since 2.0.0; :nsq since 2.1.0)
# @return [Array]
def values (which = :all)
case which
when :all then @seq + values(:spr) + @rnd.values
when :ary then @seq + values(:spr)
+ when :nsq then values(:spr) + @rnd.values
when :rnd then @rnd.values
when :seq then Array.new @seq
when :spr then @spr.values_at(*@spr.keys.sort)
else []
end