mrbgems/mruby-hash-ext/README.md
This mrbgem extends the core Hash class in mruby, providing a collection of additional methods to enhance its functionality. These extensions offer more ways to manipulate and interact with hashes, drawing inspiration from common Ruby hash methods.
To incorporate mruby-hash-ext into your mruby project, add it to your build_config.rb file. For example:
MRuby::Build.new do |conf|
# ... other configurations ...
conf.gem :github => 'mruby/mruby-hash-ext'
# or if you have it locally:
# conf.gem "#{root}/mrbgems/mruby-hash-ext"
end
Then, rebuild your mruby project. The extended hash methods will then be available for use.
This gem implements the following methods for the Hash class:
values_at(*keys): Returns an array containing the values associated with the given keys.slice(*keys): Returns a hash containing only the given keys and their values.except(*keys): Returns a hash excluding the given keys and their values.Hash.[](*object): Creates a new hash populated with the given objects.#merge!(other_hash..), #update(other_hash..): Adds the contents of other_hash to hsh.#compact!: Removes all nil values from the hash.#compact: Returns a new hash with the nil values/key pairs removed.#fetch(key [, default]), #fetch(key) {| key | block }: Returns a value from the hash for the given key.#delete_if {| key, value | block }: Deletes every key-value pair from hsh for which block evaluates to true.#flatten: Returns a new array that is a one-dimensional flattening of this hash.#invert: Returns a new hash created by using hsh's values as keys, and the keys as values.#keep_if {| key, value | block }: Deletes every key-value pair from hsh for which block evaluates to false.#key(value): Returns the key of an occurrence of a given value.#to_h: Returns self. If called on a subclass of Hash, converts the receiver to a Hash object.#< other_hash: Returns true if hsh is a subset of other_hash.#<= other_hash: Returns true if hsh is a subset of other_hash or equal to other_hash.#> other_hash: Returns true if other_hash is a subset of hsh.#>= other_hash: Returns true if other_hash is a subset of hsh or equal to hsh.#dig(key, ...): Extracts the nested value specified by the sequence of keys.#transform_keys {|key| block }: Returns a new hash with keys transformed by the block.#transform_keys! {|key| block }: Modifies the hash by transforming its keys using the block.#transform_values {|value| block }: Returns a new hash with values transformed by the block.#transform_values! {|value| block }: Modifies the hash by transforming its values using the block.#to_proc: Returns a proc that maps a key to its value in the hash.#fetch_values(key, ...): Returns an array of values for the given keys, raising KeyError if any are not found.#filter {| key, value | block } (Alias for select): Returns a new hash containing entries for which the block returns true.#filter! {| key, value | block } (Alias for select!): Modifies the hash, keeping only entries for which the block returns true.values_at(*keys) -> arrayReturns an array containing the values associated with the given keys. If a key is not found, nil is returned for that key's position in the array.
h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
h.values_at("cow", "cat") #=> ["bovine", "feline"]
h.values_at("dog", "mouse") #=> ["canine", nil]
h.values_at() #=> []
slice(*keys) -> new_hashReturns a new hash containing only the given keys and their associated values from the original hash. If a key is not found in the original hash, it's ignored.
h = { a: 100, b: 200, c: 300 }
h.slice(:a) #=> {a: 100}
h.slice(:b, :c, :d) #=> {b: 200, c: 300} (ignores :d as it's not in h)
h.slice() #=> {}
except(*keys) -> new_hashReturns a new hash containing all key-value pairs from the original hash except for those specified by the given keys. If a key is not found in the original hash, it's ignored.
h = { a: 100, b: 200, c: 300 }
h.except(:a) #=> {b: 200, c: 300}
h.except(:b, :c, :d) #=> {a: 100} (ignores :d as it's not in h)
h.except() #=> {a: 100, b: 200, c: 300}
Hash.[](*object)Creates a new hash populated with the given objects.
Hash[key, value, ...]: Creates a new hash with key-value pairs.Hash[[ [key, value], ... ]]: Creates a new hash from an array of key-value pairs.Hash[object]: Creates a new hash from an object convertible to a hash.h1 = Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200}
h2 = Hash[[ ["a", 100], ["b", 200] ]] #=> {"a"=>100, "b"=>200}
h3 = Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200}
#merge!(other_hash..) -> hsh#merge!(other_hash..){|key, oldval, newval| block} -> hsh(Alias: #update)
Adds the contents of other_hash to hsh. If no block is specified, entries with duplicate keys are overwritten with the values from other_hash. Otherwise, the value of each duplicate key is determined by calling the block with the key, its value in hsh, and its value in other_hash.
h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge!(h2) #=> {"a"=>100, "b"=>254, "c"=>300}
h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge!(h2) { |key, v1, v2| v1 }
#=> {"a"=>100, "b"=>200, "c"=>300}
#compact! -> hshRemoves all nil values from the hash. Returns the hash. Returns nil if the hash does not contain nil values.
h = { a: 1, b: false, c: nil }
h.compact! #=> { a: 1, b: false }
#compact -> new_hshReturns a new hash with the nil values/key pairs removed.
h = { a: 1, b: false, c: nil }
h.compact #=> { a: 1, b: false }
h #=> { a: 1, b: false, c: nil }
#fetch(key [, default] ) -> obj#fetch(key) {| key | block } -> objReturns a value from the hash for the given key. If the key can't be found, there are several options:
KeyError exception.default is given, then that will be returned.h = { "a" => 100, "b" => 200 }
h.fetch("a") #=> 100
h.fetch("z", "go fish") #=> "go fish"
h.fetch("z") { |el| "go fish, #{el}"} #=> "go fish, z"
# h.fetch("z") # Raises KeyError: key not found: "z"
#delete_if {| key, value | block } -> hsh#delete_if -> an_enumeratorDeletes every key-value pair from hsh for which block evaluates to true.
If no block is given, an enumerator is returned instead.
h = { "a" => 100, "b" => 200, "c" => 300 }
h.delete_if {|key, value| key >= "b" } #=> {"a"=>100}
#flatten -> an_array#flatten(level) -> an_arrayReturns a new array that is a one-dimensional flattening of this hash. That is, for every key or value that is an array, extract its elements into the new array. Unlike Array#flatten, this method does not flatten recursively by default. The optional level argument determines the level of recursion to flatten.
a = {1=> "one", 2 => [2,"two"], 3 => "three"}
a.flatten # => [1, "one", 2, [2, "two"], 3, "three"]
a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"]
#invert -> new_hashReturns a new hash created by using hsh's values as keys, and the keys as values. If a value appears more than once, the last key encountered will be used due to hash key uniqueness.
h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }
h.invert #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"}
#keep_if {| key, value | block } -> hsh#keep_if -> an_enumeratorDeletes every key-value pair from hsh for which block evaluates to false.
If no block is given, an enumerator is returned instead.
h = { "a" => 1, "b" => 2, "c" => 3, "d" => 4 }
h.keep_if {|key, value| value % 2 == 0 } #=> {"b"=>2, "d"=>4}
#key(value) -> keyReturns the key of an occurrence of a given value. If the value is not found, returns nil.
h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300 }
h.key(200) #=> "b"
h.key(300) #=> "c" (returns the first key found for the value)
h.key(999) #=> nil
#to_h -> hsh or new_hashReturns self. If called on a subclass of Hash, converts the receiver to a Hash object. For a Hash instance, it simply returns self.
h = { "a" => 1, "b" => 2 }
h.to_h #=> {"a"=>1, "b"=>2}
class MyHash < Hash; end
my_h = MyHash["c" => 3, "d" => 4]
my_h.to_h #=> {"c"=>3, "d"=>4} (returns a Hash object, not MyHash)
#< other_hash -> true or falseReturns true if hsh is a proper subset of other_hash (i.e., other_hash contains all key/value pairs of hsh, and other_hash has at least one additional key/value pair).
h1 = {a:1, b:2}
h2 = {a:1, b:2, c:3}
h1 < h2 #=> true
h2 < h1 #=> false
h1 < h1 #=> false
#<= other_hash -> true or falseReturns true if hsh is a subset of other_hash or is equal to other_hash (i.e., other_hash contains all key/value pairs of hsh).
h1 = {a:1, b:2}
h2 = {a:1, b:2, c:3}
h1 <= h2 #=> true
h2 <= h1 #=> false
h1 <= h1 #=> true
#> other_hash -> true or falseReturns true if other_hash is a proper subset of hsh (i.e., hsh contains all key/value pairs of other_hash, and hsh has at least one additional key/value pair).
h1 = {a:1, b:2}
h2 = {a:1, b:2, c:3}
h1 > h2 #=> false
h2 > h1 #=> true
h1 > h1 #=> false
#>= other_hash -> true or falseReturns true if other_hash is a subset of hsh or is equal to hsh (i.e., hsh contains all key/value pairs of other_hash).
h1 = {a:1, b:2}
h2 = {a:1, b:2, c:3}
h1 >= h2 #=> false
h2 >= h1 #=> true
h1 >= h1 #=> true
#dig(key,...) -> objectExtracts the nested value specified by the sequence of key objects by calling dig at each step. Returns nil if any intermediate step is nil.
h = { a: { b: { c: 1 } } }
h.dig(:a, :b, :c) #=> 1
h.dig(:a, :x, :c) #=> nil
g = { a: [1, 2, {b: 3}] }
g.dig(:a, 2, :b) #=> 3
g.dig(:a, 1, :b) #=> nil (element at index 1 is 2, which does not respond to #dig)
#transform_keys {|key| block } -> new_hash#transform_keys -> an_enumeratorReturns a new hash, with the keys computed from running the block once for each key in the hash, and the values unchanged. If no block is given, an enumerator is returned instead.
h = { a: 1, b: 2, c: 3 }
h.transform_keys {|k| k.to_s.upcase } #=> {"A"=>1, "B"=>2, "C"=>3}
#transform_keys! {|key| block } -> hsh#transform_keys! -> an_enumeratorInvokes the given block once for each key in hsh, replacing it with the new key returned by the block, and then returns hsh.
If no block is given, an enumerator is returned instead.
h = { a: 1, b: 2, c: 3 }
h.transform_keys! {|k| k.to_s.upcase } #=> {"A"=>1, "B"=>2, "C"=>3}
h #=> {"A"=>1, "B"=>2, "C"=>3}
#transform_values {|value| block } -> new_hash#transform_values -> an_enumeratorReturns a new hash with the results of running the block once for every value. This method does not change the keys. If no block is given, an enumerator is returned instead.
h = { a: 1, b: 2, c: 3 }
h.transform_values {|v| v * v } #=> {a: 1, b: 4, c: 9}
#transform_values! {|value| block } -> hsh#transform_values! -> an_enumeratorInvokes the given block once for each value in the hash, replacing it with the new value returned by the block, and then returns hsh.
If no block is given, an enumerator is returned instead.
h = { a: 1, b: 2, c: 3 }
h.transform_values! {|v| v * v } #=> {a: 1, b: 4, c: 9}
h #=> {a: 1, b: 4, c: 9}
#to_proc -> a_procReturns a Proc object that maps a key to its corresponding value in the hash. This allows a hash to be used as a block argument.
h = {a: 1, b: 2}
p = h.to_proc
p.call(:a) #=> 1
['a', 'b', 'c'].map(&h) #=> [1, 2, nil] (uses h[x] for each element)
#fetch_values(key, ...) -> array#fetch_values(key, ...) { |key| block } -> arrayReturns an array containing the values associated with the given keys. Raises KeyError if any of the keys can't be found, unless a block is provided to compute a default value.
h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
h.fetch_values("cow", "cat") #=> ["bovine", "feline"]
# h.fetch_values("cow", "bird") # raises KeyError: key not found: "bird"
h.fetch_values("cow", "bird") { |k| k.upcase } #=> ["bovine", "BIRD"]
#filter {| key, value | block } -> new_hsh#filter -> an_enumerator(Alias for select)
Returns a new hash consisting of entries for which the block returns a true value.
If no block is given, an enumerator is returned instead.
h = { "a" => 100, "b" => 200, "c" => 300 }
h.filter {|key, value| key < "b"} #=> {"a"=>100}
h.filter {|key, value| value < 200} #=> {"a"=>100}
#filter! {| key, value | block } -> hsh_or_nil#filter! -> an_enumerator(Alias for select!)
Equivalent to Hash#keep_if, but returns nil if no changes were made.
Deletes every key-value pair from hsh for which block evaluates to false.
If no block is given, an enumerator is returned instead.
h = { "a" => 100, "b" => 200, "c" => 300 }
h.filter! {|key, value| key < "b"} #=> {"a"=>100}
h #=> {"a"=>100}
h.filter! {|key, value| key < "a"} #=> nil (no changes)