Creates a new hash populated with the given objects.
Similar to the literal `{ key => value, … }`. In the first form, keys and values occur in pairs, so there must be an even number of arguments.
The second and third form take a single argument which is either an array of key-value pairs or an object convertible to a hash.
Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200} Hash[ [ ["a", 100], ["b", 200] ] ] #=> {"a"=>100, "b"=>200} Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200}
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 26
def self.[](*object)
length = object.length
if length == 1
o = object[0]
if Hash === o
h = self.new
o.each { |k, v| h[k] = v }
return h
elsif o.respond_to?(:to_a)
h = self.new
o.to_a.each do |i|
raise ArgumentError, "wrong element type #{i.class} (expected array)" unless i.respond_to?(:to_a)
k, v = nil
case i.size
when 2
k = i[0]
v = i[1]
when 1
k = i[0]
else
raise ArgumentError, "invalid number of elements (#{i.size} for 1..2)"
end
h[k] = v
end
return h
end
end
unless length % 2 == 0
raise ArgumentError, 'odd number of arguments for Hash'
end
h = self.new
0.step(length - 2, 2) do |i|
h[object[i]] = object[i + 1]
end
h
end
Returns true if hash is subset of other.
h1 = {a:1, b:2} h2 = {a:1, b:2, c:3} h1 < h2 #=> true h2 < h1 #=> false h1 < h1 #=> false
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 312
def <(hash)
raise TypeError, "can't convert #{hash.class} to Hash" unless Hash === hash
size < hash.size and all? {|key, val|
hash.key?(key) and hash[key] == val
}
end
Returns true if hash is subset of other or
equals to other.
h1 = {a:1, b:2} h2 = {a:1, b:2, c:3} h1 <= h2 #=> true h2 <= h1 #=> false h1 <= h1 #=> true
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 332
def <=(hash)
raise TypeError, "can't convert #{hash.class} to Hash" unless Hash === hash
size <= hash.size and all? {|key, val|
hash.key?(key) and hash[key] == val
}
end
Equality---Two hashes are equal if they each contain the same number of keys and if each key-value pair is equal to (according to <code>Object#==</code>) the corresponding elements in the other hash.
ISO 15.2.13.4.1
# File mrblib/hash.rb, line 13
def ==(hash)
return true if self.equal?(hash)
unless Hash === hash
return false
end
return false if self.size != hash.size
self.each do |k,v|
return false unless hash.key?(k)
return false unless self[k] == hash[k]
end
return true
end
Returns true if other is subset of hash.
h1 = {a:1, b:2} h2 = {a:1, b:2, c:3} h1 > h2 #=> false h2 > h1 #=> true h1 > h1 #=> false
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 352
def >(hash)
raise TypeError, "can't convert #{hash.class} to Hash" unless Hash === hash
size > hash.size and hash.all? {|key, val|
key?(key) and self[key] == val
}
end
Returns true if other is subset of hash or
equals to hash.
h1 = {a:1, b:2} h2 = {a:1, b:2, c:3} h1 >= h2 #=> false h2 >= h1 #=> true h1 >= h1 #=> true
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 372
def >=(hash)
raise TypeError, "can't convert #{hash.class} to Hash" unless Hash === hash
size >= hash.size and hash.all? {|key, val|
key?(key) and self[key] == val
}
end
internal method for Hash inspection
# File mrblib/hash.rb, line 189
def _inspect(recur_list)
return "{}" if self.size == 0
return "{...}" if recur_list[self.object_id]
recur_list[self.object_id] = true
ary=[]
keys=self.keys
size=keys.size
i=0
while i<size
k=keys[i]
ary<<(k._inspect(recur_list) + "=>" + self[k]._inspect(recur_list))
i+=1
end
"{"+ary.join(", ")+"}"
end
Returns 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 }
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 133
def compact
h = {}
self.keys.select{|k|
self[k] != nil
}.each {|k|
h[k] = self[k]
}
h
end
Removes 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 }
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 109
def compact!
keys = self.keys
nk = keys.select{|k|
self[k] != nil
}
return nil if (keys.size == nk.size)
h = {}
nk.each {|k|
h[k] = self[k]
}
h
self.replace(h)
end
Delete the element with the key key. Return the value of the
element if key was found. Return nil if nothing was found. If
a block is given, call the block with the value of the element.
ISO 15.2.13.4.8
# File mrblib/hash.rb, line 52
def delete(key, &block)
if block && !self.has_key?(key)
return block.call(key)
end
self.__delete(key)
end
Deletes 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}
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 199
def delete_if(&block)
return to_enum :delete_if unless block
self.each do |k, v|
self.delete(k) if block.call(k, v)
end
self
end
Extracts the nested value specified by the sequence of key objects
by calling dig at each step, returning nil if any
intermediate step is nil.
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 387
def dig(idx,*args)
n = self[idx]
if args.size > 0
n&.dig(*args)
else
n
end
end
Calls the given block for each element of self and pass the
key and value of each element.
If no block is given, an enumerator is returned instead.
h = { "a" => 100, "b" => 200 } h.each {|key, value| puts "#{key} is #{value}" }
produces:
a is 100 b is 200
ISO 15.2.13.4.9
# File mrblib/hash.rb, line 81
def each(&block)
return to_enum :each unless block
keys = self.keys
vals = self.values
len = self.size
i = 0
while i < len
block.call [keys[i], vals[i]]
i += 1
end
self
end
Calls the given block for each element of self and pass the
key of each element.
If no block is given, an enumerator is returned instead.
h = { "a" => 100, "b" => 200 } h.each_key {|key| puts key }
produces:
a b
ISO 15.2.13.4.10
# File mrblib/hash.rb, line 114
def each_key(&block)
return to_enum :each_key unless block
self.keys.each{|k| block.call(k)}
self
end
ISO does not define #each_pair, so #each_pair is defined in gem.
Calls the given block for each element of self and pass the
value of each element.
If no block is given, an enumerator is returned instead.
h = { "a" => 100, "b" => 200 } h.each_value {|value| puts value }
produces:
100 200
ISO 15.2.13.4.11
# File mrblib/hash.rb, line 140
def each_value(&block)
return to_enum :each_value unless block
self.keys.each{|k| block.call(self[k])}
self
end
Returns true if hash and other are both
hashes with the same content compared by eql?.
ISO 15.2.13.4.32 (x)
# File mrblib/hash.rb, line 31
def eql?(hash)
return true if self.equal?(hash)
unless Hash === hash
return false
end
return false if self.size != hash.size
self.each do |k,v|
return false unless hash.key?(k)
return false unless self[k].eql?(hash[k])
end
return true
end
Returns a value from the hash for the given key. If the key can't be
found, there are several options: With no other arguments, it will raise an
KeyError exception; if default is given, then that
will be returned; if the optional code block is specified, then that will
be run and its result 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"
The following example shows that an exception is raised if the key is not found and a default value is not supplied.
h = { "a" => 100, "b" => 200 } h.fetch("z")
produces:
prog.rb:2:in 'fetch': key not found (KeyError) from prog.rb:2
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 171
def fetch(key, none=NONE, &block)
unless self.key?(key)
if block
block.call(key)
elsif none != NONE
none
else
raise KeyError, "Key not found: #{key.inspect}"
end
else
self[key]
end
end
Returns an array containing the values associated with the given keys but
also raises KeyError when one of keys can't be found. Also
see Hash#values_at and Hash#fetch.
h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" } h.fetch_values("cow", "cat") #=> ["bovine", "feline"] h.fetch_values("cow", "bird") # raises KeyError h.fetch_values("cow", "bird") { |k| k.upcase } #=> ["bovine", "BIRD"]
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 492
def fetch_values(*keys, &block)
keys.map do |k|
self.fetch(k, &block)
end
end
Returns 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"]
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 224
def flatten(level=1)
self.to_a.flatten(level)
end
Return the contents of this hash as a string.
ISO 15.2.13.4.30 (x)
# File mrblib/hash.rb, line 208
def inspect
self._inspect({})
end
Returns a new hash created by using hsh's values as keys, and the keys as values.
h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 } h.invert #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"}
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 239
def invert
h = self.class.new
self.each {|k, v| h[v] = k }
h
end
Deletes every key-value pair from hsh for which block evaluates to false.
If no block is given, an enumerator is returned instead.
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 256
def keep_if(&block)
return to_enum :keep_if unless block
keys = []
self.each do |k, v|
unless block.call([k, v])
self.delete(k)
end
end
self
end
Returns 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" h.key(999) #=> nil
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 281
def key(val)
self.each do |k, v|
return k if v == val
end
nil
end
Return a hash which contains the content of self and
other. If a block is given it will be called for each element
with a duplicate key. The value of the block will be the final value of
this element.
ISO 15.2.13.4.22
# File mrblib/hash.rb, line 175
def merge(other, &block)
raise TypeError, "Hash required (#{other.class} given)" unless Hash === other
h = self.dup
if block
other.each_key{|k|
h[k] = (self.has_key?(k))? block.call(k, self[k], other[k]): other[k]
}
else
other.each_key{|k| h[k] = other[k]}
end
h
end
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}
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 84
def merge!(other, &block)
raise TypeError, "Hash required (#{other.class} given)" unless Hash === other
if block
other.each_key{|k|
self[k] = (self.has_key?(k))? block.call(k, self[k], other[k]): other[k]
}
else
other.each_key{|k| self[k] = other[k]}
end
self
end
Returns a new hash consisting of entries for which the block returns false.
If no block is given, an enumerator is returned instead.
h = { "a" => 100, "b" => 200, "c" => 300 } h.reject {|k,v| k < "b"} #=> {"b" => 200, "c" => 300} h.reject {|k,v| v > 100} #=> {"a" => 100}
1.8/1.9 #reject returns Hash; ISO says nothing.
# File mrblib/hash.rb, line 255
def reject(&block)
return to_enum :reject unless block
h = {}
self.each{|k,v|
unless block.call([k, v])
h[k] = v
end
}
h
end
Equivalent to Hash#delete_if, but returns nil if
no changes were made.
1.8/1.9 #reject! returns Hash; ISO says nothing.
# File mrblib/hash.rb, line 224
def reject!(&block)
return to_enum :reject! unless block
keys = []
self.each{|k,v|
if block.call([k, v])
keys.push(k)
end
}
return nil if keys.size == 0
keys.each{|k|
self.delete(k)
}
self
end
Replaces the contents of hsh with the contents of other hash
ISO 15.2.13.4.23
# File mrblib/hash.rb, line 151
def replace(hash)
raise TypeError, "Hash required (#{hash.class} given)" unless Hash === hash
self.clear
hash.each_key{|k|
self[k] = hash[k]
}
if hash.default_proc
self.default_proc = hash.default_proc
else
self.default = hash.default
end
self
end
Returns a new hash consisting of entries for which the block returns true.
If no block is given, an enumerator is returned instead.
h = { "a" => 100, "b" => 200, "c" => 300 } h.select {|k,v| k > "a"} #=> {"b" => 200, "c" => 300} h.select {|k,v| v < 200} #=> {"a" => 100}
1.9 #select returns Hash; ISO says nothing
# File mrblib/hash.rb, line 308
def select(&block)
return to_enum :select unless block
h = {}
self.each{|k,v|
if block.call([k, v])
h[k] = v
end
}
h
end
Equivalent to Hash#keep_if, but returns nil if no
changes were made.
1.9 #select! returns Hash; ISO says nothing.
# File mrblib/hash.rb, line 277
def select!(&block)
return to_enum :select! unless block
keys = []
self.each{|k,v|
unless block.call([k, v])
keys.push(k)
end
}
return nil if keys.size == 0
keys.each{|k|
self.delete(k)
}
self
end
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 473
def to_proc
->x{self[x]}
end
Returns 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.
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 406
def transform_keys(&block)
return to_enum :transform_keys unless block
hash = {}
self.keys.each do |k|
new_key = block.call(k)
hash[new_key] = self[k]
end
hash
end
Invokes 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.
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 425
def transform_keys!(&block)
return to_enum :transform_keys! unless block
self.keys.each do |k|
value = self[k]
self.__delete(k)
k = block.call(k) if block
self[k] = value
end
self
end
Returns 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.
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 446
def transform_values(&b)
return to_enum :transform_values unless block_given?
hash = {}
self.keys.each do |k|
hash[k] = yield(self[k])
end
hash
end
Invokes the given block once for each value in the hash, replacing with the new value returned by the block, and then returns hsh.
If no block is given, an enumerator is returned instead.
# File mrbgems/mruby-hash-ext/mrblib/hash.rb, line 465
def transform_values!(&b)
return to_enum :transform_values! unless block_given?
self.keys.each do |k|
self[k] = yield(self[k])
end
self
end