Class: Hamster::Hash

Inherits:
Object
  • Object
show all
Includes:
Associable, Enumerable
Defined in:
lib/hamster/hash.rb

Overview

A Hamster::Hash maps a set of unique keys to corresponding values, much like a dictionary maps from words to definitions. Given a key, it can store and retrieve an associated value in constant time. If an existing key is stored again, the new value will replace the old. It behaves much like Ruby's built-in Hash, which we will call RubyHash for clarity. Like RubyHash, two keys that are #eql? to each other and have the same #hash are considered identical in a Hamster::Hash.

A Hamster::Hash can be created in a couple of ways:

Hamster::Hash.new(font_size: 10, font_family: 'Arial')
Hamster::Hash[first_name: 'John', last_name: 'Smith']

Any Enumerable object which yields two-element [key, value] arrays can be used to initialize a Hamster::Hash:

Hamster::Hash.new([[:first_name, 'John'], [:last_name, 'Smith']])

Key/value pairs can be added using #put. A new hash is returned and the existing one is left unchanged:

hash = Hamster::Hash[a: 100, b: 200]
hash.put(:c, 500) # => Hamster::Hash[:a => 100, :b => 200, :c => 500]
hash              # => Hamster::Hash[:a => 100, :b => 200]

#put can also take a block, which is used to calculate the value to be stored.

hash.put(:a) { |current| current + 200 } # => Hamster::Hash[:a => 300, :b => 200]

Since it is immutable, all methods which you might expect to "modify" a Hamster::Hash actually return a new hash and leave the existing one unchanged. This means that the hash[key] = value syntax from RubyHash cannot be used with Hamster::Hash.

Nested data structures can easily be updated using Associable#update_in:

hash = Hamster::Hash["a" => Hamster::Vector[Hamster::Hash["c" => 42]]]
hash.update_in("a", 0, "c") { |value| value + 5 }
# => Hamster::Hash["a" => Hamster::Hash["b" => Hamster::Hash["c" => 47]]]

While a Hamster::Hash can iterate over its keys or values, it does not guarantee any specific iteration order (unlike RubyHash). Methods like #flatten do not guarantee the order of returned key/value pairs.

Like RubyHash, a Hamster::Hash can have a default block which is used when looking up a key that does not exist. Unlike RubyHash, the default block will only be passed the missing key, without the hash itself:

hash = Hamster::Hash.new { |missing_key| missing_key * 10 }
hash[5] # => 50

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Associable

#dig, #update_in

Methods included from Enumerable

#<=>, #compact, #each_index, #grep, #grep_v, #group_by, #join, #partition, #product, #reject, #sum, #to_set

Methods included from Enumerable

#to_list

Constructor Details

#initialize(pairs = nil) {|key| ... } ⇒ Hash

Returns a new instance of Hash.

Parameters:

  • pairs (::Enumerable) (defaults to: nil)

    initial content of hash. An empty hash is returned if not provided.

Yields:

  • (key)

    Optional default block to be stored and used to calculate the default value of a missing key. It will not be yielded during this method. It will not be preserved when marshalling.

Yield Parameters:

  • key

    Key that was not present in the hash.



103
104
105
106
# File 'lib/hamster/hash.rb', line 103

def initialize(pairs = nil, &block)
  @trie = pairs ? Trie[pairs] : EmptyTrie
  @default = block
end

Class Method Details

.[](pairs = nil) ⇒ Hash

Create a new Hash populated with the given key/value pairs.

Examples:

Hamster::Hash["A" => 1, "B" => 2] # => Hamster::Hash["A" => 1, "B" => 2]
Hamster::Hash[["A", 1], ["B", 2]] # => Hamster::Hash["A" => 1, "B" => 2]

Parameters:

  • pairs (::Enumerable) (defaults to: nil)

    initial content of hash. An empty hash is returned if not provided.

Returns:



75
76
77
# File 'lib/hamster/hash.rb', line 75

def [](pairs = nil)
  (pairs.nil? || pairs.empty?) ? empty : new(pairs)
end

.emptyHash

Return an empty Hash. If used on a subclass, returns an empty instance of that class.

Returns:



83
84
85
# File 'lib/hamster/hash.rb', line 83

def empty
  @empty ||= self.new
end

Instance Method Details

#<(other) ⇒ Boolean

Return true if this Hash is a proper subset of other, which means all its keys are contained in other with the identical values, and the two hashes are not identical.

Parameters:

Returns:

  • (Boolean)


779
780
781
# File 'lib/hamster/hash.rb', line 779

def <(other)
  other > self
end

#<=(other) ⇒ Boolean

Return true if this Hash is a subset of other, which means all its keys are contained in other with the identical values, and the two hashes are not identical.

Parameters:

Returns:

  • (Boolean)


789
790
791
# File 'lib/hamster/hash.rb', line 789

def <=(other)
  other >= self
end

#==(other) ⇒ Boolean

Return true if other has the same contents as this Hash. Will convert other to a Ruby Hash using #to_hash if necessary.

Parameters:

  • other (Object)

    The object to compare with

Returns:

  • (Boolean)


745
746
747
# File 'lib/hamster/hash.rb', line 745

def ==(other)
  self.eql?(other) || (other.respond_to?(:to_hash) && to_hash == other.to_hash)
end

#>(other) ⇒ Boolean

Return true if this Hash is a proper superset of other, which means all other's keys are contained in this Hash with the identical values, and the two hashes are not identical.

Parameters:

Returns:

  • (Boolean)


755
756
757
# File 'lib/hamster/hash.rb', line 755

def >(other)
  self != other && self >= other
end

#>=(other) ⇒ Boolean

Return true if this Hash is a superset of other, which means all other's keys are contained in this Hash with the identical values.

Parameters:

Returns:

  • (Boolean)


764
765
766
767
768
769
770
771
# File 'lib/hamster/hash.rb', line 764

def >=(other)
  other.each do |key, value|
    if self[key] != value
      return false
    end
  end
  true
end

#assoc(obj) ⇒ Array

Searches through the Hash, comparing obj with each key (using #==). When a matching key is found, return the [key, value] pair as an array. Return nil if no match is found.

Examples:

Hamster::Hash["A" => 1, "B" => 2, "C" => 3].assoc("B")  # => ["B", 2]

Parameters:

  • obj (Object)

    The key to search for (using #==)

Returns:

  • (Array)


673
674
675
676
# File 'lib/hamster/hash.rb', line 673

def assoc(obj)
  each { |entry| return entry if obj == entry[0] }
  nil
end

#clearHash

Return an empty Hash instance, of the same class as this one. Useful if you have multiple subclasses of Hash and want to treat them polymorphically. Maintains the default block, if there is one.

Returns:



723
724
725
726
727
728
729
# File 'lib/hamster/hash.rb', line 723

def clear
  if @default
    self.class.alloc(EmptyTrie, @default)
  else
    self.class.empty
  end
end

#default_procProc

Return the default block if there is one. Otherwise, return nil.

Returns:

  • (Proc)


111
112
113
# File 'lib/hamster/hash.rb', line 111

def default_proc
  @default
end

#delete(key) ⇒ Hash

Return a new Hash with key removed. If key is not present, return self.

Examples:

Hamster::Hash["A" => 1, "B" => 2, "C" => 3].delete("B")
# => Hamster::Hash["A" => 1, "C" => 3]

Parameters:

  • key (Object)

    The key to remove

Returns:



317
318
319
# File 'lib/hamster/hash.rb', line 317

def delete(key)
  derive_new_hash(@trie.delete(key))
end

#each {|key, value| ... } ⇒ self Also known as: each_pair

Call the block once for each key/value pair in this Hash, passing the key/value pair as parameters. No specific iteration order is guaranteed, though the order will be stable for any particular Hash.

Examples:

Hamster::Hash["A" => 1, "B" => 2, "C" => 3].each { |k, v| puts "k=#{k} v=#{v}" }

k=A v=1
k=C v=3
k=B v=2
# => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]

Yields:

  • (key, value)

    Once for each key/value pair.

Returns:

  • (self)


335
336
337
338
339
# File 'lib/hamster/hash.rb', line 335

def each(&block)
  return to_enum if not block_given?
  @trie.each(&block)
  self
end

#each_key {|key| ... } ⇒ self

Call the block once for each key/value pair in this Hash, passing the key as a parameter. Ordering guarantees are the same as #each.

Examples:

Hamster::Hash["A" => 1, "B" => 2, "C" => 3].each_key { |k| puts "k=#{k}" }

k=A
k=C
k=B
# => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]

Yields:

  • (key)

    Once for each key/value pair.

Returns:

  • (self)


374
375
376
377
378
# File 'lib/hamster/hash.rb', line 374

def each_key
  return enum_for(:each_key) if not block_given?
  @trie.each { |k,v| yield k }
  self
end

#each_value {|value| ... } ⇒ self

Call the block once for each key/value pair in this Hash, passing the value as a parameter. Ordering guarantees are the same as #each.

Examples:

Hamster::Hash["A" => 1, "B" => 2, "C" => 3].each_value { |v| puts "v=#{v}" }

v=1
v=3
v=2
# => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]

Yields:

  • (value)

    Once for each key/value pair.

Returns:

  • (self)


393
394
395
396
397
# File 'lib/hamster/hash.rb', line 393

def each_value
  return enum_for(:each_value) if not block_given?
  @trie.each { |k,v| yield v }
  self
end

#empty?Boolean

Return true if this Hash contains no key/value pairs.

Returns:

  • (Boolean)


129
130
131
# File 'lib/hamster/hash.rb', line 129

def empty?
  @trie.empty?
end

#eql?(other) ⇒ Boolean

Return true if other has the same type and contents as this Hash.

Parameters:

  • other (Object)

    The collection to compare with

Returns:

  • (Boolean)


735
736
737
738
# File 'lib/hamster/hash.rb', line 735

def eql?(other)
  return true if other.equal?(self)
  instance_of?(other.class) && @trie.eql?(other.instance_variable_get(:@trie))
end

#except(*keys) ⇒ Hash

Return a new Hash with the associations for all of the given keys removed.

Examples:

h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
h.except("A", "C")  # => Hamster::Hash["B" => 2]

Parameters:

  • keys (Array)

    The keys to remove

Returns:



549
550
551
# File 'lib/hamster/hash.rb', line 549

def except(*keys)
  keys.reduce(self) { |hash, key| hash.delete(key) }
end

#fetch(key) ⇒ Object #fetch(key) {|key| ... } ⇒ Object #fetch(key, default) ⇒ Object

Retrieve the value corresponding to the given key object, or use the provided default value or block, or otherwise raise a KeyError.

Examples:

h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
h.fetch("B")         # => 2
h.fetch("Elephant")  # => KeyError: key not found: "Elephant"

# with a default value:
h.fetch("B", 99)         # => 2
h.fetch("Elephant", 99)  # => 99

# with a block:
h.fetch("B") { |key| key.size }         # => 2
h.fetch("Elephant") { |key| key.size }  # => 8

Overloads:

  • #fetch(key) ⇒ Object

    Retrieve the value corresponding to the given key, or raise a KeyError if it is not found.

    Parameters:

    • key (Object)

      The key to look up

  • #fetch(key) {|key| ... } ⇒ Object

    Retrieve the value corresponding to the given key, or call the optional code block (with the missing key) and get its return value.

    Parameters:

    • key (Object)

      The key to look up

    Yields:

    • (key)

      The key which was not found

    Yield Returns:

    • (Object)

      Object to return since the key was not found

  • #fetch(key, default) ⇒ Object

    Retrieve the value corresponding to the given key, or else return the provided default value.

    Parameters:

    • key (Object)

      The key to look up

    • default (Object)

      Object to return if the key is not found

Returns:

  • (Object)


222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/hamster/hash.rb', line 222

def fetch(key, default = Undefined)
  entry = @trie.get(key)
  if entry
    entry[1]
  elsif block_given?
    yield(key)
  elsif default != Undefined
    default
  else
    raise KeyError, "key not found: #{key.inspect}"
  end
end

#fetch_values(*wanted) ⇒ Vector

Return a Vector of the values which correspond to the wanted keys. If any of the wanted keys are not present in this Hash, raise KeyError exception.

Examples:

h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
h.fetch_values("C", "A")  # => Hamster::Vector[3, 1]
h.fetch_values("C", "Z")  # => KeyError: key not found: "Z"

Parameters:

  • wanted (Array)

    The keys to retrieve

Returns:



594
595
596
597
# File 'lib/hamster/hash.rb', line 594

def fetch_values(*wanted)
  array = wanted.map { |key| fetch(key) }
  Vector.new(array.freeze)
end

#find {|key, value| ... } ⇒ Array Also known as: detect

Yield [key, value] pairs until one is found for which the block returns true. Return that [key, value] pair. If the block never returns true, return nil.

Examples:

h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
h.find { |k, v| v.even? }
# => ["B", 2]

Yields:

  • (key, value)

    At most once for each key/value pair, until the block returns true.

Yield Returns:

  • Truthy to halt iteration and return the yielded key/value pair.

Returns:

  • (Array)


445
446
447
448
449
# File 'lib/hamster/hash.rb', line 445

def find
  return enum_for(:find) unless block_given?
  each { |entry| return entry if yield entry }
  nil
end

#flatten(level = 1) ⇒ Vector

Return a new Vector which is a one-dimensional flattening of this Hash. If level is 1, all the [key, value] pairs in the hash will be concatenated into one Vector. If level is greater than 1, keys or values which are themselves Arrays or Vectors will be recursively flattened into the output Vector. The depth to which that flattening will be recursively applied is determined by level.

As a special case, if level is 0, each [key, value] pair will be a separate element in the returned Vector.

Examples:

h = Hamster::Hash["A" => 1, "B" => [2, 3, 4]]
h.flatten
# => Hamster::Vector["A", 1, "B", [2, 3, 4]]
h.flatten(2)
# => Hamster::Vector["A", 1, "B", 2, 3, 4]

Parameters:

  • level (Integer) (defaults to: 1)

    The number of times to recursively flatten the [key, value] pairs in this Hash.

Returns:



656
657
658
659
660
661
662
# File 'lib/hamster/hash.rb', line 656

def flatten(level = 1)
  return Vector.new(self) if level == 0
  array = []
  each { |k,v| array << k; array << v }
  array.flatten!(level-1) if level > 1
  Vector.new(array.freeze)
end

#get(key) ⇒ Object Also known as: []

Retrieve the value corresponding to the provided key object. If not found, and this Hash has a default block, the default block is called to provide the value. Otherwise, return nil.

Examples:

h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
h["B"]             # => 2
h.get("B")         # => 2
h.get("Elephant")  # => nil

# Hamster Hash with a default proc:
h = Hamster::Hash.new("A" => 1, "B" => 2, "C" => 3) { |key| key.size }
h.get("B")         # => 2
h.get("Elephant")  # => 8

Parameters:

  • key (Object)

    The key to look up

Returns:

  • (Object)


179
180
181
182
183
184
185
186
# File 'lib/hamster/hash.rb', line 179

def get(key)
  entry = @trie.get(key)
  if entry
    entry[1]
  elsif @default
    @default.call(key)
  end
end

#hashInteger

See Object#hash.

Returns:

  • (Integer)


795
796
797
798
799
# File 'lib/hamster/hash.rb', line 795

def hash
  keys.to_a.sort.reduce(0) do |hash, key|
    (hash << 32) - hash + key.hash + get(key).hash
  end
end

#inspectString

Return the contents of this Hash as a programmer-readable String. If all the keys and values are serializable as Ruby literal strings, the returned string can be passed to eval to reconstitute an equivalent Hash. The default block (if there is one) will be lost when doing this, however.

Returns:

  • (String)


807
808
809
810
811
812
813
814
815
816
# File 'lib/hamster/hash.rb', line 807

def inspect
  result = "#{self.class}["
  i = 0
  each do |key, val|
    result << ', ' if i > 0
    result << key.inspect << ' => ' << val.inspect
    i += 1
  end
  result << "]"
end

#invertHash

Return a new Hash created by using keys as values and values as keys. If there are multiple values which are equivalent (as determined by #hash and #eql?), only one out of each group of equivalent values will be retained. Which one specifically is undefined.

Examples:

Hamster::Hash["A" => 1, "B" => 2, "C" => 3, "D" => 2].invert
# => Hamster::Hash[1 => "A", 3 => "C", 2 => "B"]

Returns:



631
632
633
634
635
# File 'lib/hamster/hash.rb', line 631

def invert
  pairs = []
  each { |k,v| pairs << [v, k] }
  self.class.new(pairs, &@default)
end

#key(value) ⇒ Object

Searches through the Hash, comparing value with each value (using #==). When a matching value is found, return its associated key object. Return nil if no match is found.

Examples:

Hamster::Hash["A" => 1, "B" => 2, "C" => 3].key(2)  # => "B"

Parameters:

  • value (Object)

    The value to search for (using #==)

Returns:

  • (Object)


701
702
703
704
# File 'lib/hamster/hash.rb', line 701

def key(value)
  each { |entry| return entry[0] if value == entry[1] }
  nil
end

#key?(key) ⇒ Boolean Also known as: has_key?, include?, member?

Return true if the given key object is present in this Hash. More precisely, return true if a key with the same #hash code, and which is also #eql? to the given key object is present.

Examples:

Hamster::Hash["A" => 1, "B" => 2, "C" => 3].key?("B")  # => true

Parameters:

  • key (Object)

    The key to check for

Returns:

  • (Boolean)


142
143
144
# File 'lib/hamster/hash.rb', line 142

def key?(key)
  @trie.key?(key)
end

#keysSet

Return a new Set containing the keys from this Hash.

Examples:

Hamster::Hash["A" => 1, "B" => 2, "C" => 3, "D" => 2].keys
# => Hamster::Set["D", "C", "B", "A"]

Returns:



606
607
608
# File 'lib/hamster/hash.rb', line 606

def keys
  Set.alloc(@trie)
end

#map {|key, value| ... } ⇒ Hash Also known as: collect

Call the block once for each key/value pair in this Hash, passing the key/value pair as parameters. The block should return a [key, value] array each time. All the returned [key, value] arrays will be gathered into a new Hash.

Examples:

h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
h.map { |k, v| ["new-#{k}", v * v] }
# => Hash["new-C" => 9, "new-B" => 4, "new-A" => 1]

Yields:

  • (key, value)

    Once for each key/value pair.

Returns:



410
411
412
413
414
# File 'lib/hamster/hash.rb', line 410

def map
  return enum_for(:map) unless block_given?
  return self if empty?
  self.class.new(super, &@default)
end

#merge(other) {|key, my_value, other_value| ... } ⇒ Hash

Return a new Hash containing all the key/value pairs from this Hash and other. If no block is provided, the value for entries with colliding keys will be that from other. Otherwise, the value for each duplicate key is determined by calling the block.

other can be a Hamster::Hash, a built-in Ruby Hash, or any Enumerable object which yields [key, value] pairs.

Examples:

h1 = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
h2 = Hamster::Hash["C" => 70, "D" => 80]
h1.merge(h2)
# => Hamster::Hash["C" => 70, "A" => 1, "D" => 80, "B" => 2]
h1.merge(h2) { |key, v1, v2| v1 + v2 }
# => Hamster::Hash["C" => 73, "A" => 1, "D" => 80, "B" => 2]

Parameters:

Yield Parameters:

  • key (Object)

    The key which was present in both collections

  • my_value (Object)

    The associated value from this Hash

  • other_value (Object)

    The associated value from the other collection

Yield Returns:

  • (Object)

    The value to associate this key with in the new Hash

Returns:



474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
# File 'lib/hamster/hash.rb', line 474

def merge(other)
  trie = if block_given?
    other.reduce(@trie) do |trie, (key, value)|
      if entry = trie.get(key)
        trie.put(key, yield(key, entry[1], value))
      else
        trie.put(key, value)
      end
    end
  else
    @trie.bulk_put(other)
  end

  derive_new_hash(trie)
end

#put(key, value = yield(get(key))) {|value| ... } ⇒ Hash

Return a new Hash with the existing key/value associations, plus an association between the provided key and value. If an equivalent key is already present, its associated value will be replaced with the provided one.

If the value argument is missing, but an optional code block is provided, it will be passed the existing value (or nil if there is none) and what it returns will replace the existing value. This is useful for "transforming" the value associated with a certain key.

Avoid mutating objects which are used as keys. Strings are an exception: unfrozen Strings which are used as keys are internally duplicated and frozen. This matches RubyHash's behaviour.

Examples:

h = Hamster::Hash["A" => 1, "B" => 2]
h.put("C", 3)
# => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
h.put("B") { |value| value * 10 }
# => Hamster::Hash["A" => 1, "B" => 20]

Parameters:

  • key (Object)

    The key to store

  • value (Object) (defaults to: yield(get(key)))

    The value to associate it with

Yields:

  • (value)

    The previously stored value, or nil if none.

Yield Returns:

  • (Object)

    The new value to store

Returns:



260
261
262
263
264
265
266
267
# File 'lib/hamster/hash.rb', line 260

def put(key, value = yield(get(key)))
  new_trie = @trie.put(key, value)
  if new_trie.equal?(@trie)
    self
  else
    self.class.alloc(new_trie, @default)
  end
end

#rassoc(obj) ⇒ Array

Searches through the Hash, comparing obj with each value (using #==). When a matching value is found, return the [key, value] pair as an array. Return nil if no match is found.

Examples:

Hamster::Hash["A" => 1, "B" => 2, "C" => 3].rassoc(2)  # => ["B", 2]

Parameters:

  • obj (Object)

    The value to search for (using #==)

Returns:

  • (Array)


687
688
689
690
# File 'lib/hamster/hash.rb', line 687

def rassoc(obj)
  each { |entry| return entry if obj == entry[1] }
  nil
end

#reverse_each {|key, value| ... } ⇒ self

Call the block once for each key/value pair in this Hash, passing the key/value pair as parameters. Iteration order will be the opposite of #each.

Examples:

Hamster::Hash["A" => 1, "B" => 2, "C" => 3].reverse_each { |k, v| puts "k=#{k} v=#{v}" }

k=B v=2
k=C v=3
k=A v=1
# => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]

Yields:

  • (key, value)

    Once for each key/value pair.

Returns:

  • (self)


355
356
357
358
359
# File 'lib/hamster/hash.rb', line 355

def reverse_each(&block)
  return enum_for(:reverse_each) if not block_given?
  @trie.reverse_each(&block)
  self
end

#sampleArray

Return a randomly chosen [key, value] pair from this Hash. If the hash is empty, return nil.

Examples:

Hamster::Hash["A" => 1, "B" => 2, "C" => 3].sample
# => ["C", 3]

Returns:

  • (Array)


714
715
716
# File 'lib/hamster/hash.rb', line 714

def sample
  @trie.at(rand(size))
end

#select {|key, value| ... } ⇒ Hash Also known as: find_all, keep_if

Return a new Hash with all the key/value pairs for which the block returns true.

Examples:

h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
h.select { |k, v| v >= 2 }
# => Hamster::Hash["B" => 2, "C" => 3]

Yields:

  • (key, value)

    Once for each key/value pair.

Yield Returns:

  • Truthy if this pair should be present in the new Hash.

Returns:



427
428
429
430
# File 'lib/hamster/hash.rb', line 427

def select(&block)
  return enum_for(:select) unless block_given?
  derive_new_hash(@trie.select(&block))
end

#sizeInteger Also known as: length

Return the number of key/value pairs in this Hash.

Examples:

Hamster::Hash["A" => 1, "B" => 2, "C" => 3].size  # => 3

Returns:

  • (Integer)


121
122
123
# File 'lib/hamster/hash.rb', line 121

def size
  @trie.size
end

#slice(*wanted) ⇒ Hash

Return a new Hash with only the associations for the wanted keys retained.

Examples:

h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
h.slice("B", "C")  # => Hamster::Hash["B" => 2, "C" => 3]

Parameters:

Returns:



561
562
563
564
565
# File 'lib/hamster/hash.rb', line 561

def slice(*wanted)
  trie = Trie.new(0)
  wanted.each { |key| trie.put!(key, get(key)) if key?(key) }
  self.class.alloc(trie, @default)
end

#sortVector #sort({ |(k1, v1), (k2, v2)| ... }) {|(k1, v1), (k2, v2)| ... } ⇒ Vector

Return a sorted Vector which contains all the [key, value] pairs in this Hash as two-element Arrays.

Overloads:

  • #sortVector

    Uses #<=> to determine sorted order.

  • #sort({ |(k1, v1), (k2, v2)| ... }) {|(k1, v1), (k2, v2)| ... } ⇒ Vector

    Uses the block as a comparator to determine sorted order.

    Examples:

    h = Hamster::Hash["Dog" => 1, "Elephant" => 2, "Lion" => 3]
    h.sort { |(k1, v1), (k2, v2)| k1.size  <=> k2.size }
    # => Hamster::Vector[["Dog", 1], ["Lion", 3], ["Elephant", 2]]

    Yields:

    • ((k1, v1), (k2, v2))

      Any number of times with different pairs of key/value associations.

    Yield Returns:

    • (Integer)

      Negative if the first pair should be sorted lower, positive if the latter pair, or 0 if equal.

Returns:

See Also:

  • Enumerable#sort


518
519
520
# File 'lib/hamster/hash.rb', line 518

def sort
  Vector.new(super)
end

#sort_by {|key, value| ... } ⇒ Vector

Return a Vector which contains all the [key, value] pairs in this Hash as two-element Arrays. The order which the pairs will appear in is determined by passing each pair to the code block to obtain a sort key object, and comparing the sort keys using #<=>.

Examples:

h = Hamster::Hash["Dog" => 1, "Elephant" => 2, "Lion" => 3]
h.sort_by { |key, value| key.size }
# => Hamster::Vector[["Dog", 1], ["Lion", 3], ["Elephant", 2]]

Yields:

  • (key, value)

    Once for each key/value pair.

Yield Returns:

  • a sort key object for the yielded pair.

Returns:

See Also:

  • Enumerable#sort_by


537
538
539
# File 'lib/hamster/hash.rb', line 537

def sort_by
  Vector.new(super)
end

#store(key, value) ⇒ Hash

An alias for #put to match RubyHash's API. Does not support #put's block form.

Parameters:

  • key (Object)

    The key to store

  • value (Object)

    The value to associate it with

Returns:

See Also:



304
305
306
# File 'lib/hamster/hash.rb', line 304

def store(key, value)
  put(key, value)
end

#to_hash::Hash Also known as: to_h

Convert this Hamster::Hash to an instance of Ruby's built-in Hash.

Returns:

  • (::Hash)


843
844
845
846
847
848
849
# File 'lib/hamster/hash.rb', line 843

def to_hash
  output = {}
  each do |key, value|
    output[key] = value
  end
  output
end

#to_procProc

Return a Proc which accepts a key as an argument and returns the value. The Proc behaves like #get (when the key is missing, it returns nil or result of the default proc).

Examples:

h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
h.to_proc.call("B")
# => 2
["A", "C", "X"].map(&h)   # The & is short for .to_proc in Ruby
# => [1, 3, nil]

Returns:

  • (Proc)


864
865
866
# File 'lib/hamster/hash.rb', line 864

def to_proc
  lambda { |key| get(key) }
end

#value?(value) ⇒ Boolean Also known as: has_value?

Return true if this Hash has one or more keys which map to the provided value.

Examples:

Hamster::Hash["A" => 1, "B" => 2, "C" => 3].value?(2)  # => true

Parameters:

  • value (Object)

    The value to check for

Returns:

  • (Boolean)


156
157
158
159
# File 'lib/hamster/hash.rb', line 156

def value?(value)
  each { |k,v| return true if value == v }
  false
end

#valuesVector

Return a new Vector populated with the values from this Hash.

Examples:

Hamster::Hash["A" => 1, "B" => 2, "C" => 3, "D" => 2].values
# => Hamster::Vector[2, 3, 2, 1]

Returns:



617
618
619
# File 'lib/hamster/hash.rb', line 617

def values
  Vector.new(each_value.to_a.freeze)
end

#values_at(*wanted) ⇒ Vector

Return a Vector of the values which correspond to the wanted keys. If any of the wanted keys are not present in this Hash, nil will be placed instead, or the result of the default proc (if one is defined), similar to the behavior of #get.

Examples:

h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
h.values_at("B", "A", "D")  # => Hamster::Vector[2, 1, nil]

Parameters:

  • wanted (Array)

    The keys to retrieve

Returns:



578
579
580
581
# File 'lib/hamster/hash.rb', line 578

def values_at(*wanted)
  array = wanted.map { |key| get(key) }
  Vector.new(array.freeze)
end