Class: Hamster::Hash

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

Overview

A Hamster::Hash maps from a set of unique keys to corresponding values, much like a dictionary maps from words to definitions. Given a key, it can efficiently store and retrieve values. Looking up a key given its value is also possible, but less efficient. If an existing key is stored again, the new value will replace that which was previously stored.

It behaves much like Ruby's built-in Hash, which we will call RubyHash for clarity. Like RubyHash, Hamster::Hash uses #hash and #eql? to define equality between keys. Keys with the same #hash code, but which are not #eql? to each other, can coexist in the same Hamster::Hash. To retrieve a previously stored value, the key provided must have the same #hash code and be #eql? to the one used for storage.

A Hamster::Hash can be created in several ways:

Hamster.hash('Jane Doe' => 10, 'Jim Doe' => 6)
Hamster::Hash.new(font_size: 10, font_family: 'Arial')
Hamster::Hash[first_name: 'John', last_name: 'Smith']

If you want to write your own class which inherits from Hamster::Hash, you can use either of the latter 2 forms of initialization.

Note that any Enumerable object which yields 2-element [key, value] arrays can be used to initialize a Hamster::Hash. So this is also possible:

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

Like RubyHash, key/value pairs can be added using #store. Unlike RubyHash, a new hash is returned, and the existing one is left unchanged:

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

You also use #put. The difference is that #put can optionally take a block which is used to calculate the value to be stored:

hash.put(:a) { hash[:b] + 100 } # => 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 used with RubyHashes cannot be used with Hamster::Hash.

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

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

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

A default block can only be set when creating a Hamster::Hash with Hamster::Hash.new or Hamster.hash, not with Hamster::Hash[]. Default blocks do not survive marshalling and unmarshalling.

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Enumerable

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

Methods included from Enumerable

#to_list

Constructor Details

#initialize(pairs = nil, &block) ⇒ Hash


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

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]

87
88
89
# File 'lib/hamster/hash.rb', line 87

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.


95
96
97
# File 'lib/hamster/hash.rb', line 95

def empty
  @empty ||= self.new
end

Instance Method Details

#==(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.


725
726
727
# File 'lib/hamster/hash.rb', line 725

def ==(other)
  self.eql?(other) || (other.respond_to?(:to_hash) && to_hash.eql?(other.to_hash))
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]

653
654
655
656
# File 'lib/hamster/hash.rb', line 653

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.


703
704
705
706
707
708
709
# File 'lib/hamster/hash.rb', line 703

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.


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

def default_proc
  @default
end

#delete(key) ⇒ Hash

Return a new Hash with the association for 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]

341
342
343
# File 'lib/hamster/hash.rb', line 341

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

#each(&block) ⇒ 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 (but 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=B v=2
k=C v=3
# => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]

358
359
360
361
362
# File 'lib/hamster/hash.rb', line 358

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

#each_keyself

Call the block once for each key/value pair in this Hash, passing the key as a parameter.

Examples:

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

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

395
396
397
398
399
# File 'lib/hamster/hash.rb', line 395

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

#each_valueself

Call the block once for each key/value pair in this Hash, passing the value as a parameter.

Examples:

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

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

413
414
415
416
417
# File 'lib/hamster/hash.rb', line 413

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.


138
139
140
# File 'lib/hamster/hash.rb', line 138

def empty?
  @trie.empty?
end

#eql?(other) ⇒ Boolean

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


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

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]

545
546
547
# File 'lib/hamster/hash.rb', line 545

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.

  • #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.

    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.


231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/hamster/hash.rb', line 231

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

#findArray 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]

460
461
462
463
464
# File 'lib/hamster/hash.rb', line 460

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]

636
637
638
639
640
641
642
# File 'lib/hamster/hash.rb', line 636

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.

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

188
189
190
191
192
193
194
195
# File 'lib/hamster/hash.rb', line 188

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

#hashInteger

See Object#hash.


731
732
733
734
735
# File 'lib/hamster/hash.rb', line 731

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. However, the default block (if there is one) will be lost when doing this.


743
744
745
746
747
748
749
750
751
752
# File 'lib/hamster/hash.rb', line 743

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 our 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.

Examples:

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

611
612
613
614
615
# File 'lib/hamster/hash.rb', line 611

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"

681
682
683
684
# File 'lib/hamster/hash.rb', line 681

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

151
152
153
# File 'lib/hamster/hash.rb', line 151

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

#keysSet

Return a new Set populated with the keys from this Hash.

Examples:

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

587
588
589
# File 'lib/hamster/hash.rb', line 587

def keys
  Set.alloc(@trie)
end

#mapHash 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]

429
430
431
432
433
# File 'lib/hamster/hash.rb', line 429

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. Otherwie, the value for each duplicate key is determined by called the block with the key, its value in this Hash, and its value in other.

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]

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


490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
# File 'lib/hamster/hash.rb', line 490

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.

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]

Yields:

  • (value)

    The previously stored value

Yield Returns:

  • (Object)

    The new value to store


269
270
271
272
273
274
275
276
# File 'lib/hamster/hash.rb', line 269

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]

667
668
669
670
# File 'lib/hamster/hash.rb', line 667

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

#reverse_each(&block) ⇒ 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=C v=3
k=B v=2
k=A v=1
# => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]

377
378
379
380
381
# File 'lib/hamster/hash.rb', line 377

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]

694
695
696
# File 'lib/hamster/hash.rb', line 694

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

#select(&block) ⇒ 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]

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

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

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

def size
  @trie.size
end

#slice(*wanted) ⇒ Hash

Return a new Hash with only the associations for the wanted keys retained. If any of the wanted keys are not present in this Hash, they will not be present in the returned Hash either.

Examples:

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

559
560
561
562
563
# File 'lib/hamster/hash.rb', line 559

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

Return a Vector which contains all the [key, value] pairs in this Hash as 2-element Arrays, either in their natural sorted order as determined by #<=>, or if an optional block is supplied, by using the block as a comparator. See Enumerable#sort.

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]]

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

def sort
  Vector.new(super)
end

#sort_byVector

Return a Vector which contains all the [key, value] pairs in this Hash as 2-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 #<=>. See Enumerable#sort_by.

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]]

533
534
535
# File 'lib/hamster/hash.rb', line 533

def sort_by
  Vector.new(super)
end

#store(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.

Avoid mutating objects which are used as keys. Strings are an exception -- unfrozen Strings which are used as keys are internally duplicated and frozen.

Examples:

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

328
329
330
# File 'lib/hamster/hash.rb', line 328

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.


779
780
781
782
783
784
785
# File 'lib/hamster/hash.rb', line 779

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

#to_ruby::Hash

Deeply convert to Ruby Hash.


791
792
793
# File 'lib/hamster/hash.rb', line 791

def to_ruby
  Hamster.to_ruby(self)
end

#update_in(*key_path) {|value| ... } ⇒ Hash

Return a new Hash with a deeply nested value modified to the result of the given code block. When traversing the nested Hashes and Vectors, non-existing keys are created with empty Hash values.

The code block receives the existing value of the deeply nested key (or nil if it doesn't exist). This is useful for "transforming" the value associated with a certain key.

Note that the original Hash and sub-Hashes and sub-Vectors are left unmodified; new data structure copies are created along the path wherever needed.

Examples:

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

Yields:

  • (value)

    The previously stored value

Yield Returns:

  • (Object)

    The new value to store


299
300
301
302
303
304
305
306
307
308
309
310
311
# File 'lib/hamster/hash.rb', line 299

def update_in(*key_path, &block)
  if key_path.empty?
    raise ArgumentError, "must have at least one key in path"
  end
  key = key_path[0]
  if key_path.size == 1
    new_value = block.call(get(key))
  else
    value = fetch(key, EmptyHash)
    new_value = value.update_in(*key_path[1..-1], &block)
  end
  put(key, new_value)
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

165
166
167
168
# File 'lib/hamster/hash.rb', line 165

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]

598
599
600
# File 'lib/hamster/hash.rb', line 598

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, they will be skipped.

Examples:

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

574
575
576
577
578
# File 'lib/hamster/hash.rb', line 574

def values_at(*wanted)
  array = []
  wanted.each { |key| array << get(key) if key?(key) }
  Vector.new(array.freeze)
end