Class: Hash
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Instance Chain:
self,
::Enumerable
|
|
Inherits: | Object |
Defined in: | hash.c, hash.c, hash.rb |
Overview
A Hash object maps each of its unique keys to a specific value.
A hash has certain similarities to an ::Array
, but:
-
An array index is always an integer.
-
A hash key can be (almost) any object.
Hash Data Syntax
The original syntax for a hash entry uses the “hash rocket,” =>
:
h = {:foo => 0, : => 1, :baz => 2}
h # => {foo: 0, bar: 1, baz: 2}
Alternatively, but only for a key that’s a symbol, you can use a newer JSON-style syntax, where each bareword becomes a symbol:
h = {foo: 0, bar: 1, baz: 2}
h # => {foo: 0, bar: 1, baz: 2}
You can also use a string in place of a bareword:
h = {'foo': 0, 'bar': 1, 'baz': 2}
h # => {foo: 0, bar: 1, baz: 2}
And you can mix the styles:
h = {foo: 0, : => 1, 'baz': 2}
h # => {foo: 0, bar: 1, baz: 2}
But it’s an error to try the JSON-style syntax for a key that’s not a bareword or a string:
# Raises SyntaxError (syntax error, unexpected ':', expecting =>):
h = {0: 'zero'}
The value can be omitted, meaning that value will be fetched from the context by the name of the key:
x = 0
y = 100
h = {x:, y:}
h # => {x: 0, y: 100}
Common Uses
You can use a hash to give names to objects:
person = {name: 'Matz', language: 'Ruby'}
person # => {name: "Matz", language: "Ruby"}
You can use a hash to give names to method arguments:
def some_method(hash)
p hash
end
some_method({foo: 0, bar: 1, baz: 2}) # => {foo: 0, bar: 1, baz: 2}
Note: when the last argument in a method call is a hash, the curly braces may be omitted:
some_method(foo: 0, bar: 1, baz: 2) # => {foo: 0, bar: 1, baz: 2}
You can use a hash to initialize an object:
class Dev
attr_accessor :name, :language
def initialize(hash)
self.name = hash[:name]
self.language = hash[:language]
end
end
matz = Dev.new(name: 'Matz', language: 'Ruby')
matz # => #<Dev: @name="Matz", @language="Ruby">
Creating a Hash
You can create a Hash object explicitly with:
-
A hash literal.
You can convert certain objects to hashes with:
You can create a hash by calling method .new:
# Create an empty hash.
h = Hash.new
h # => {}
h.class # => Hash
You can create a hash by calling method .[]:
# Create an empty hash.
h = Hash[]
h # => {}
# Create a hash with initial entries.
h = Hash[foo: 0, bar: 1, baz: 2]
h # => {foo: 0, bar: 1, baz: 2}
You can create a hash by using its literal form (curly braces):
# Create an empty hash.
h = {}
h # => {}
# Create a {Hash} with initial entries.
h = {foo: 0, bar: 1, baz: 2}
h # => {foo: 0, bar: 1, baz: 2}
Hash Value Basics
The simplest way to retrieve a hash value (instance method #[]):
h = {foo: 0, bar: 1, baz: 2}
h[:foo] # => 0
The simplest way to create or update a hash value (instance method #[]=):
h = {foo: 0, bar: 1, baz: 2}
h[:bat] = 3 # => 3
h # => {foo: 0, bar: 1, baz: 2, bat: 3}
h[:foo] = 4 # => 4
h # => {foo: 4, bar: 1, baz: 2, bat: 3}
The simplest way to delete a hash entry (instance method #delete):
h = {foo: 0, bar: 1, baz: 2}
h.delete(: ) # => 1
h # => {foo: 0, baz: 2}
Entry Order
A Hash object presents its entries in the order of their creation. This is seen in:
-
Iterative methods such as #each, #each_key, #each_pair, #each_value.
-
Other order-sensitive methods such as #shift, #keys, #values.
-
The string returned by method #inspect.
A new hash has its initial ordering per the given entries:
h = Hash[foo: 0, bar: 1]
h # => {foo: 0, bar: 1}
New entries are added at the end:
h[:baz] = 2
h # => {foo: 0, bar: 1, baz: 2}
Updating a value does not affect the order:
h[:baz] = 3
h # => {foo: 0, bar: 1, baz: 3}
But re-creating a deleted entry can affect the order:
h.delete(:foo)
h[:foo] = 5
h # => {bar: 1, baz: 3, foo: 5}
Hash
Keys
Hash
Key Equivalence
Two objects are treated as the same hash key when their #hash value is identical and the two objects are #eql? to each other.
Modifying an Active Hash
Key
Modifying a Hash
key while it is in use damages the hash’s index.
This Hash
has keys that are Arrays:
a0 = [ :foo, : ]
a1 = [ :baz, :bat ]
h = {a0 => 0, a1 => 1}
h.include?(a0) # => true
h[a0] # => 0
a0.hash # => 110002110
Modifying array element a0[0]
changes its hash value:
a0[0] = :bam
a0.hash # => 1069447059
And damages the Hash
index:
h.include?(a0) # => false
h[a0] # => nil
You can repair the hash index using method #rehash:
h.rehash # => {[:bam, :bar]=>0, [:baz, :bat]=>1}
h.include?(a0) # => true
h[a0] # => 0
A String key is always safe. That’s because an unfrozen ::String
passed as a key will be replaced by a duplicated and frozen ::String
:
s = 'foo'
s.frozen? # => false
h = {s => 0}
first_key = h.keys.first
first_key.frozen? # => true
User-Defined Hash
Keys
To be usable as a Hash
key, objects must implement the methods #hash and #eql?. Note: this requirement does not apply if the Hash
uses #compare_by_identity since comparison will then rely on the keys’ object id instead of #hash and #eql?.
::Object
defines basic implementation for #hash and eq?
that makes each object a distinct key. Typically, user-defined classes will want to override these methods to provide meaningful behavior, or for example inherit ::Struct
that has useful definitions for these.
A typical implementation of #hash is based on the object’s data while #eql? is usually aliased to the overridden #== method:
class Book
attr_reader :, :title
def initialize(, title)
@author =
@title = title
end
def ==(other)
self.class === other &&
other. == @author &&
other.title == @title
end
alias eql? ==
def hash
[self.class, @author, @title].hash
end
end
book1 = Book.new 'matz', 'Ruby in a Nutshell'
book2 = Book.new 'matz', 'Ruby in a Nutshell'
reviews = {}
reviews[book1] = 'Great reference!'
reviews[book2] = 'Nice and compact!'
reviews.length #=> 1
Key Not Found?
When a method tries to retrieve and return the value for a key and that key is found, the returned value is the value associated with the key.
But what if the key is not found? In that case, certain methods will return a default value while other will raise a KeyError.
Nil Return Value
If you want nil
returned for a not-found key, you can call:
-
#[](key) (usually written as
#[key]
. -
#assoc(key).
-
#dig(key, *identifiers).
-
#values_at(*keys).
You can override these behaviors for #[], #dig, and #values_at (but not #assoc); see Default.
KeyError
If you want ::KeyError
raised for a not-found key, you can call:
-
#fetch(key).
-
#fetch_values(*keys).
Hash Default
For certain methods (#[], #dig, and #values_at), the return value for a not-found key is determined by two hash properties:
-
default value: returned by method #default.
-
default proc: returned by method #default_proc.
In the simple case, both values are nil
, and the methods return nil
for a not-found key; see Nil Return Value above.
Note that this entire section (“Hash Default”):
-
Applies only to methods #[], #dig, and #values_at.
-
Does not apply to methods #assoc, #fetch, or #fetch_values, which are not affected by the default value or default proc.
Any-Key Default
You can define an any-key default for a hash; that is, a value that will be returned for any not-found key:
-
The value of #default_proc must be
nil
. -
The value of #default (which may be any object, including
nil
) will be returned for a not-found key.
You can set the default value when the hash is created with .new and option default_value
, or later with method #default=.
Note: although the value of #default may be any object, it may not be a good idea to use a mutable object.
Per-Key Defaults
You can define a per-key default for a hash; that is, a ::Proc
that will return a value based on the key itself.
You can set the default proc when the hash is created with .new and a block, or later with method #default_proc=.
Note that the proc can modify self
, but modifying self
in this way is not thread-safe; multiple threads can concurrently call into the default proc for the same key.
Method Default
For two methods, you can specify a default value for a not-found key that has effect only for a single method call (and not for any subsequent calls):
-
For method #fetch, you can specify an any-key default:
-
For either method #fetch or method #fetch_values, you can specify a per-key default via a block.
What’s Here
First, what’s elsewhere. ::Class
Hash
:
-
Inherits from class Object.
-
Includes module Enumerable, which provides dozens of additional methods.
Here, class Hash
provides methods that are useful for:
-
{Hash#label-Methods+for+Creating+a+Hash Creating a }
::Class
Hash
also includes methods from module ::Enumerable
.
Methods for Creating a Hash
-
.[]: Returns a new hash populated with given objects.
-
.new: Returns a new empty hash.
-
.try_convert: Returns a new hash created from a given object.
Methods for Setting Hash
State
-
#compare_by_identity: Sets
self
to consider only identity in comparing keys. -
#default=: Sets the default to a given value.
-
#default_proc=: Sets the default proc to a given proc.
-
#rehash: Rebuilds the hash table by recomputing the hash index for each key.
Methods for Querying
-
#any?: Returns whether any element satisfies a given criterion.
-
#compare_by_identity?: Returns whether the hash considers only identity when comparing keys.
-
#default: Returns the default value, or the default value for a given key.
-
#default_proc: Returns the default proc.
-
#empty?: Returns whether there are no entries.
-
#eql?: Returns whether a given object is equal to
self
. -
#hash: Returns the integer hash code.
-
#has_value? (aliased as #value?): Returns whether a given object is a value in
self
. -
#include? (aliased as #has_key?, #member?, #key?): Returns whether a given object is a key in
self
.
Methods for Comparing
-
#<: Returns whether
self
is a proper subset of a given object. -
#<=: Returns whether
self
is a subset of a given object. -
#==: Returns whether a given object is equal to
self
. -
#>: Returns whether
self
is a proper superset of a given object -
#>=: Returns whether
self
is a superset of a given object.
Methods for Fetching
-
#[]: Returns the value associated with a given key.
-
#assoc: Returns a 2-element array containing a given key and its value.
-
#dig: Returns the object in nested objects that is specified by a given key and additional arguments.
-
#fetch: Returns the value for a given key.
-
#fetch_values: Returns array containing the values associated with given keys.
-
#key: Returns the key for the first-found entry with a given value.
-
#keys: Returns an array containing all keys in
self
. -
#rassoc: Returns a 2-element array consisting of the key and value of the first-found entry having a given value.
-
#values: Returns an array containing all values in
self
. -
#values_at: Returns an array containing values for given keys.
Methods for Assigning
-
#[]= (aliased as #store): Associates a given key with a given value.
-
#merge: Returns the hash formed by merging each given hash into a copy of
self
. -
#update (aliased as #merge!): Merges each given hash into
self
. -
#replace (aliased as #initialize_copy): Replaces the entire contents of
self
with the contents of a given hash.
Methods for Deleting
These methods remove entries from self
:
-
#clear: Removes all entries from
self
. -
#compact!: Removes all
nil
-valued entries fromself
. -
#delete: Removes the entry for a given key.
-
#delete_if: Removes entries selected by a given block.
-
#select! (aliased as #filter!): Keep only those entries selected by a given block.
-
#keep_if: Keep only those entries selected by a given block.
-
#reject!: Removes entries selected by a given block.
-
#shift: Removes and returns the first entry.
These methods return a copy of self
with some entries removed:
-
#compact: Returns a copy of
self
with allnil
-valued entries removed. -
#except: Returns a copy of
self
with entries removed for specified keys. -
#select (aliased as #filter): Returns a copy of
self
with only those entries selected by a given block. -
#reject: Returns a copy of
self
with entries removed as specified by a given block. -
#slice: Returns a hash containing the entries for given keys.
Methods for Iterating
-
#each_pair (aliased as #each): Calls a given block with each key-value pair.
-
#each_key: Calls a given block with each key.
-
#each_value: Calls a given block with each value.
Methods for Converting
-
#flatten: Returns an array that is a 1-dimensional flattening of
self
. -
#inspect (aliased as #to_s): Returns a new
::String
containing the hash entries. -
#to_a: Returns a new array of 2-element arrays; each nested array contains a key-value pair from
self
. -
#to_h: Returns
self
if aHash
; if a subclass ofHash
, returns aHash
containing the entries fromself
. -
#to_hash: Returns
self
. -
#to_proc: Returns a proc that maps a given key to its value.
Methods for Transforming Keys and Values
-
#invert: Returns a hash with the each key-value pair inverted.
-
#transform_keys: Returns a copy of
self
with modified keys. -
#transform_keys!: Modifies keys in
self
-
#transform_values: Returns a copy of
self
with modified values. -
#transform_values!: Modifies values in
self
.
Class Method Summary
-
.[] ⇒ Hash
Returns a new Hash object populated with the given objects, if any.
-
.new(default_value = nil, capacity: 0) ⇒ Hash
constructor
Returns a new empty Hash object.
-
.ruby2_keywords_hash(hash) ⇒ Hash
Duplicates a given hash and adds a ruby2_keywords flag.
-
.ruby2_keywords_hash?(hash) ⇒ Boolean
Checks if a given hash is flagged by Module#ruby2_keywords (or Proc#ruby2_keywords).
-
.try_convert(object) ⇒ Object, ...
If
object
is a hash, returnsobject
.
Instance Attribute Summary
-
#compare_by_identity ⇒ self
readonly
Sets
self
to compare keys using identity (rather than mere equality); returnsself
: -
#compare_by_identity? ⇒ Boolean
readonly
Returns whether #compare_by_identity has been called:
-
#default_proc ⇒ Proc?
rw
Returns the default proc for
self
(seeHash
Default): -
#default_proc=(proc) ⇒ Proc
rw
Sets the default proc for
self
toproc
(seeHash
Default): -
#empty? ⇒ Boolean
readonly
Returns
true
if there are no hash entries,false
otherwise:
Instance Method Summary
-
#<(other_hash) ⇒ Boolean
Returns
true
if the entries ofself
are a proper subset of the entries ofother_hash
,false
otherwise: -
#<=(other_hash) ⇒ Boolean
Returns
true
if the entries ofself
are a subset of the entries ofother_hash
,false
otherwise: -
#==(object) ⇒ Boolean
Returns whether
self
andobject
are equal. -
#>(other_hash) ⇒ Boolean
Returns
true
if the entries ofself
are a proper superset of the entries ofother_hash
,false
otherwise: -
#>=(other_hash) ⇒ Boolean
Returns
true
if the entries ofself
are a superset of the entries ofother_hash
,false
otherwise: -
#[](key) ⇒ Object
Searches for a hash key equivalent to the given #key; see
Hash
Key Equivalence. -
#[]=(key, object) ⇒ Object
(also: #store)
Associates the given
object
with the given #key; returnsobject
. -
#any? ⇒ Boolean
Returns
true
if any element satisfies a given criterion;false
otherwise. -
#assoc(key) ⇒ entry?
If the given #key is found, returns its entry as a 2-element array containing that key and its value:
-
#clear ⇒ self
Removes all entries from
self
; returns emptiedself
. -
#compact ⇒ Hash
Returns a copy of
self
with allnil
-valued entries removed: -
#compact! ⇒ self?
If
self
contains anynil
-valued entries, returnsself
with allnil
-valued entries removed; returnsnil
otherwise: -
#default ⇒ Object
Returns the default value for the given #key.
-
#default=(value) ⇒ Object
Sets the default value to
value
; returnsvalue
: -
#delete(key) ⇒ value?
If an entry for the given #key is found, deletes the entry and returns its associated value; otherwise returns
nil
or calls the given block. -
#delete_if {|key, value| ... } ⇒ self
With a block given, calls the block with each key-value pair, deletes each entry for which the block returns a truthy value, and returns
self
: -
#dig(key, *identifiers) ⇒ Object
Finds and returns an object found in nested objects, as specified by #key and
identifiers
. -
#each_pair {|key, value| ... } ⇒ self
(also: #each_pair)
With a block given, calls the block with each key-value pair; returns
self
: -
#each_key {|key| ... } ⇒ self
With a block given, calls the block with each key; returns
self
: -
#each_pair {|key, value| ... } ⇒ self
Alias for #each.
-
#each_value {|value| ... } ⇒ self
With a block given, calls the block with each value; returns
self
: -
#eql?(object) ⇒ Boolean
Returns
true
if all of the following are true: - #except(*keys) ⇒ Hash
-
#fetch(key) ⇒ Object
With no block given, returns the value for the given #key, if found;.
- #fetch_values(*keys) ⇒ Array
-
#select {|key, value| ... } ⇒ Hash
(also: #select)
With a block given, calls the block with each entry’s key and value; returns a new hash whose entries are those for which the block returns a truthy value:
-
#select! {|key, value| ... } ⇒ self?
(also: #select!)
With a block given, calls the block with each entry’s key and value; removes from
self
each entry for which the block returnsfalse
ornil
. -
#flatten(depth = 1) ⇒ Array
With positive integer
depth
, returns a new array that is a recursive flattening ofself
to the givendepth
. -
#has_key?(key) ⇒ Boolean
Alias for #key?.
-
#has_value?(value) ⇒ Boolean
Alias for #value?.
-
#hash ⇒ Integer
Returns the integer hash-code for the hash.
-
#include?(key) ⇒ Boolean
Alias for #key?.
-
#initialize_copy(other_hash) ⇒ self
Alias for #replace.
-
#inspect ⇒ String
Alias for #to_s.
-
#invert ⇒ Hash
Returns a new hash with each key-value pair inverted:
-
#keep_if {|key, value| ... } ⇒ self
With a block given, calls the block for each key-value pair; retains the entry if the block returns a truthy value; otherwise deletes the entry; returns
self
: -
#key(value) ⇒ key?
Returns the key for the first-found entry with the given
value
(see Entry Order): -
#key?(key) ⇒ Boolean
(also: #include?, #member?, #has_key?)
Returns whether #key is a key in
self
: -
#keys ⇒ Array
Returns a new array containing all keys in
self
: -
#length ⇒ Integer
(also: #size)
Returns the count of entries in
self
: -
#member?(key) ⇒ Boolean
Alias for #key?.
-
#merge(*other_hashes) ⇒ Hash
Each argument
other_hash
inother_hashes
must be a hash. -
#update(*other_hashes) ⇒ self
(also: #update)
Updates values and/or adds entries to
self
; returnsself
. -
#rassoc(value) ⇒ Array?
Searches
self
for the first entry whose value is #== to the givenvalue
; see Entry Order. -
#rehash ⇒ self
Rebuilds the hash table for
self
by recomputing the hash index for each key; returnsself
. -
#reject {|key, value| ... } ⇒ Hash
With a block given, returns a copy of
self
with zero or more entries removed; calls the block with each key-value pair; excludes the entry in the copy if the block returns a truthy value, includes it otherwise: -
#reject! {|key, value| ... } ⇒ self?
With a block given, calls the block with each entry’s key and value; removes the entry from
self
if the block returns a truthy value. -
#replace(other_hash) ⇒ self
(also: #initialize_copy)
Replaces the entire contents of
self
with the contents ofother_hash
; returnsself
: -
#select {|key, value| ... } ⇒ Hash
Alias for #filter.
-
#select! {|key, value| ... } ⇒ self?
Alias for #filter!.
-
#shift ⇒ Array, value
Removes and returns the first entry of
self
as a 2-element array; see Entry Order: -
#size ⇒ Integer
Alias for #length.
-
#slice(*keys) ⇒ Hash
Returns a new hash containing the entries from
self
for the given #keys; ignores any keys that are not found: -
#store(key, object) ⇒ Object
Alias for #[]=.
-
#to_a ⇒ Array
Returns all elements of
self
as an array of 2-element arrays; each nested array contains a key-value pair fromself
: -
#to_h {|key, value| ... } ⇒ Hash
With a block given, returns a new hash whose content is based on the block; the block is called with each entry’s key and value; the block should return a 2-element array containing the key and value to be included in the returned array:
-
#to_hash ⇒ self
Returns
self
. -
#to_proc ⇒ Proc
Returns a
::Proc
object that maps a key to its value: -
#to_s ⇒ String
(also: #inspect)
Returns a new string containing the hash entries:
-
#transform_keys {|old_key| ... } ⇒ Hash
With an argument, a block, or both given, derives a new hash
new_hash
fromself
, the argument, and/or the block; all, some, or none of its keys may be different from those inself
. -
#transform_keys! {|old_key| ... } ⇒ self
With an argument, a block, or both given, derives keys from the argument, the block, and
self
; all, some, or none of the keys inself
may be changed. -
#transform_values {|value| ... } ⇒ Hash
With a block given, returns a new hash
new_hash
; for each pairkey+/+value
inself
, calls the block withvalue
and captures its return asnew_value
; adds tonew_hash
the entrykey+/+new_value
: -
#transform_values! {|old_value| ... } ⇒ self
With a block given, changes the values of
self
as determined by the block; returnsself
. -
#update(*other_hashes) ⇒ self
Alias for #merge!.
-
#value?(value) ⇒ Boolean
(also: #has_value?)
Returns whether
value
is a value inself
. -
#values ⇒ Array
Returns a new array containing all values in
self
: -
#values_at(*keys) ⇒ Array
Returns a new array containing values for the given #keys:
- #deconstruct_keys(keys) Internal use only
- #freeze Internal use only
::Enumerable
- Included
#all? | Returns whether every element meets a given criterion. |
#any? | Returns whether any element meets a given criterion. |
#chain | Returns an enumerator object generated from this enumerator and given enumerables. |
#chunk | Each element in the returned enumerator is a 2-element array consisting of: |
#chunk_while | Creates an enumerator for each chunked elements. |
#collect | Alias for Enumerable#map. |
#collect_concat | Alias for Enumerable#flat_map. |
#compact | Returns an array of all non- |
#count | Returns the count of elements, based on an argument or block criterion, if given. |
#cycle | When called with positive integer argument |
#detect | Alias for Enumerable#find. |
#drop | For positive integer |
#drop_while | Calls the block with successive elements as long as the block returns a truthy value; returns an array of all elements after that point: |
#each_cons | Calls the block with each successive overlapped |
#each_entry | Calls the given block with each element, converting multiple values from yield to an array; returns |
#each_slice | Calls the block with each successive disjoint |
#each_with_index | Invoke |
#each_with_object | Calls the block once for each element, passing both the element and the given object: |
#entries | Alias for Enumerable#to_a. |
#filter | Returns an array containing elements selected by the block. |
#filter_map | Returns an array containing truthy elements returned by the block. |
#find | Returns the first element for which the block returns a truthy value. |
#find_all | Alias for Enumerable#filter. |
#find_index | Returns the index of the first element that meets a specified criterion, or |
#first | Returns the first element or elements. |
#flat_map | Returns an array of flattened objects returned by the block. |
#grep | Returns an array of objects based elements of |
#grep_v | Returns an array of objects based on elements of |
#group_by | With a block given returns a hash: |
#include? | Alias for Enumerable#member?. |
#inject | Returns the result of applying a reducer to an initial value and the first element of the |
#lazy | Returns an |
#map | Returns an array of objects returned by the block. |
#max | Returns the element with the maximum element according to a given criterion. |
#max_by | Returns the elements for which the block returns the maximum values. |
#member? | Returns whether for any element |
#min | Returns the element with the minimum element according to a given criterion. |
#min_by | Returns the elements for which the block returns the minimum values. |
#minmax | Returns a 2-element array containing the minimum and maximum elements according to a given criterion. |
#minmax_by | Returns a 2-element array containing the elements for which the block returns minimum and maximum values: |
#none? | Returns whether no element meets a given criterion. |
#one? | Returns whether exactly one element meets a given criterion. |
#partition | With a block given, returns an array of two arrays: |
#reduce | Alias for Enumerable#inject. |
#reject | Returns an array of objects rejected by the block. |
#reverse_each | With a block given, calls the block with each element, but in reverse order; returns |
#select | Alias for Enumerable#filter. |
#slice_after | Creates an enumerator for each chunked elements. |
#slice_before | With argument |
#slice_when | Creates an enumerator for each chunked elements. |
#sort | Returns an array containing the sorted elements of |
#sort_by | With a block given, returns an array of elements of |
#sum | With no block given, returns the sum of |
#take | For non-negative integer |
#take_while | Calls the block with successive elements as long as the block returns a truthy value; returns an array of all elements up to that point: |
#tally | When argument #hash is not given, returns a new hash whose keys are the distinct elements in |
#to_a | Returns an array containing the items in |
#to_h | When |
#to_set | Makes a set from the enumerable object with given arguments. |
#uniq | With no block, returns a new array containing only unique elements; the array has no two elements |
#zip | With no block given, returns a new array |
Constructor Details
.new(default_value = nil, capacity: 0) ⇒ Hash
.new(capacity: 0) {|self, key| ... } ⇒ Hash
Hash
.new(capacity: 0) {|self, key| ... } ⇒ Hash
Returns a new empty Hash object.
Initializes the values of #default and #default_proc, which determine the behavior when a given key is not found; see Key Not Found?.
By default, a hash has nil
values for both #default and #default_proc:
h = Hash.new # => {}
h.default # => nil
h.default_proc # => nil
With argument default_value
given, sets the #default value for the hash:
h = Hash.new(false) # => {}
h.default # => false
h.default_proc # => nil
With a block given, sets the #default_proc value:
h = Hash.new {|hash, key| "Hash #{hash}: Default value for #{key}" }
h.default # => nil
h.default_proc # => #<Proc:0x00000289b6fa7048 (irb):185>
h[:nosuch] # => "Hash {}: Default value for nosuch"
Raises ArgumentError if both default_value
and a block are given.
If optional keyword argument capacity
is given with a positive integer value n
, initializes the hash with enough capacity to accommodate n
entries without resizing.
See also Methods for Creating a Hash.
# File 'hash.rb', line 37
def initialize(ifnone = (ifnone_unset = true), capacity: 0, &block) Primitive.rb_hash_init(capacity, ifnone_unset, ifnone, block) end
Class Method Details
.[] ⇒ Hash
.[](other_hash) ⇒ Hash
.[]([*2_element_arrays] ) ⇒ Hash
.[](*objects) ⇒ Hash
Hash
.[](other_hash) ⇒ Hash
.[]([*2_element_arrays] ) ⇒ Hash
.[](*objects) ⇒ Hash
Returns a new Hash object populated with the given objects, if any. See .new.
With no argument given, returns a new empty hash.
With a single argument other_hash
given that is a hash, returns a new hash initialized with the entries from that hash (but not with its #default or #default_proc):
h = {foo: 0, bar: 1, baz: 2}
Hash[h] # => {foo: 0, bar: 1, baz: 2}
With a single argument 2_element_arrays
given that is an array of 2-element arrays, returns a new hash wherein each given 2-element array forms a key-value entry:
Hash[ [ [:foo, 0], [:, 1] ] ] # => {foo: 0, bar: 1}
With an even number of arguments objects
given, returns a new hash wherein each successive pair of arguments is a key-value entry:
Hash[:foo, 0, :, 1] # => {foo: 0, bar: 1}
Raises ArgumentError if the argument list does not conform to any of the above.
See also Methods for Creating a Hash.
# File 'hash.c', line 1817
static VALUE rb_hash_s_create(int argc, VALUE *argv, VALUE klass) { VALUE hash, tmp; if (argc == 1) { tmp = rb_hash_s_try_convert(Qnil, argv[0]); if (!NIL_P(tmp)) { if (!RHASH_EMPTY_P(tmp) && rb_hash_compare_by_id_p(tmp)) { /* hash_copy for non-empty hash will copy compare_by_identity flag, but we don't want it copied. Work around by converting hash to flattened array and using that. */ tmp = rb_hash_to_a(tmp); } else { hash = hash_alloc(klass); if (!RHASH_EMPTY_P(tmp)) hash_copy(hash, tmp); return hash; } } else { tmp = rb_check_array_type(argv[0]); } if (!NIL_P(tmp)) { long i; hash = hash_alloc(klass); for (i = 0; i < RARRAY_LEN(tmp); ++i) { VALUE e = RARRAY_AREF(tmp, i); VALUE v = rb_check_array_type(e); VALUE key, val = Qnil; if (NIL_P(v)) { rb_raise(rb_eArgError, "wrong element type %s at %ld (expected array)", rb_builtin_class_name(e), i); } switch (RARRAY_LEN(v)) { default: rb_raise(rb_eArgError, "invalid number of elements (%ld for 1..2)", RARRAY_LEN(v)); case 2: val = RARRAY_AREF(v, 1); case 1: key = RARRAY_AREF(v, 0); rb_hash_aset(hash, key, val); } } return hash; } } if (argc % 2 != 0) { rb_raise(rb_eArgError, "odd number of arguments for Hash"); } hash = hash_alloc(klass); rb_hash_bulk_insert(argc, argv, hash); hash_verify(hash); return hash; }
.ruby2_keywords_hash(hash) ⇒ Hash
Duplicates a given hash and adds a ruby2_keywords flag. This method is not for casual use; debugging, researching, and some truly necessary cases like deserialization of arguments.
h = {k: 1}
h = Hash.ruby2_keywords_hash(h)
def foo(k: 42)
k
end
foo(*[h]) #=> 1 with neither a warning or an error
# File 'hash.c', line 1947
static VALUE rb_hash_s_ruby2_keywords_hash(VALUE dummy, VALUE hash) { Check_Type(hash, T_HASH); VALUE tmp = rb_hash_dup(hash); if (RHASH_EMPTY_P(hash) && rb_hash_compare_by_id_p(hash)) { rb_hash_compare_by_id(tmp); } RHASH(tmp)->basic.flags |= RHASH_PASS_AS_KEYWORDS; return tmp; }
.ruby2_keywords_hash?(hash) ⇒ Boolean
Checks if a given hash is flagged by Module#ruby2_keywords (or Proc#ruby2_keywords). This method is not for casual use; debugging, researching, and some truly necessary cases like serialization of arguments.
ruby2_keywords def foo(*args)
Hash.ruby2_keywords_hash?(args.last)
end
foo(k: 1) #=> true
foo({k: 1}) #=> false
# File 'hash.c', line 1925
static VALUE rb_hash_s_ruby2_keywords_hash_p(VALUE dummy, VALUE hash) { Check_Type(hash, T_HASH); return RBOOL(RHASH(hash)->basic.flags & RHASH_PASS_AS_KEYWORDS); }
.try_convert(object) ⇒ Object, ...
If object
is a hash, returns object
.
Otherwise if object
responds to :to_hash
, calls object.to_hash
; returns the result if it is a hash, or raises ::TypeError
if not.
Otherwise if object
does not respond to :to_hash
, returns nil
.
# File 'hash.c', line 1904
static VALUE rb_hash_s_try_convert(VALUE dummy, VALUE hash) { return rb_check_hash_type(hash); }
Instance Attribute Details
#compare_by_identity ⇒ self
(readonly)
Sets self
to compare keys using identity (rather than mere equality); returns self
:
By default, two keys are considered to be the same key if and only if they are equal objects (per method #==):
h = {}
h['x'] = 0
h['x'] = 1 # Overwrites.
h # => {"x"=>1}
When this method has been called, two keys are considered to be the same key if and only if they are the same object:
h.compare_by_identity
h['x'] = 2 # Does not overwrite.
h # => {"x"=>1, "x"=>2}
Related: #compare_by_identity?; see also Methods for Comparing.
# File 'hash.c', line 4670
VALUE rb_hash_compare_by_id(VALUE hash) { VALUE tmp; st_table *identtable; if (rb_hash_compare_by_id_p(hash)) return hash; rb_hash_modify_check(hash); if (hash_iterating_p(hash)) { rb_raise(rb_eRuntimeError, "compare_by_identity during iteration"); } if (RHASH_TABLE_EMPTY_P(hash)) { // Fast path: There's nothing to rehash, so we don't need a `tmp` table. // We're most likely an AR table, so this will need an allocation. ar_force_convert_table(hash, __FILE__, __LINE__); HASH_ASSERT(RHASH_ST_TABLE_P(hash)); RHASH_ST_TABLE(hash)->type = &identhash; } else { // Slow path: Need to rehash the members of `self` into a new // `tmp` table using the new `identhash` compare/hash functions. tmp = hash_alloc(0); hash_st_table_init(tmp, &identhash, RHASH_SIZE(hash)); identtable = RHASH_ST_TABLE(tmp); rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp); rb_hash_free(hash); // We know for sure `identtable` is an st table, // so we can skip `ar_force_convert_table` here. RHASH_ST_TABLE_SET(hash, identtable); RHASH_ST_CLEAR(tmp); } return hash; }
#compare_by_identity? ⇒ Boolean
(readonly)
Returns whether #compare_by_identity has been called:
h = {}
h.compare_by_identity? # => false
h.compare_by_identity
h.compare_by_identity? # => true
Related: #compare_by_identity; see also Methods for Comparing.
# File 'hash.c', line 4725
VALUE rb_hash_compare_by_id_p(VALUE hash) { return RBOOL(RHASH_IDENTHASH_P(hash)); }
#default_proc ⇒ Proc? (rw)
Returns the default proc for self
(see Hash
Default):
h = {}
h.default_proc # => nil
h.default_proc = proc {|hash, key| "Default value for #{key}" }
h.default_proc.class # => Proc
# File 'hash.c', line 2265
static VALUE rb_hash_default_proc(VALUE hash) { if (FL_TEST(hash, RHASH_PROC_DEFAULT)) { return RHASH_IFNONE(hash); } return Qnil; }
#default_proc=(proc) ⇒ Proc (rw)
Sets the default proc for self
to proc
(see Hash
Default):
h = {}
h.default_proc # => nil
h.default_proc = proc { |hash, key| "Default value for #{key}" }
h.default_proc.class # => Proc
h.default_proc = nil
h.default_proc # => nil
# File 'hash.c', line 2288
VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc) { VALUE b; rb_hash_modify_check(hash); if (NIL_P(proc)) { SET_DEFAULT(hash, proc); return proc; } b = rb_check_convert_type_with_id(proc, T_DATA, "Proc", idTo_proc); if (NIL_P(b) || !rb_obj_is_proc(b)) { rb_raise(rb_eTypeError, "wrong default_proc type %s (expected Proc)", rb_obj_classname(proc)); } proc = b; SET_PROC_DEFAULT(hash, proc); return proc; }
#empty? ⇒ Boolean
(readonly)
Returns true
if there are no hash entries, false
otherwise:
{}.empty? # => true
{foo: 0}.empty? # => false
Related: see Methods for Querying.
# File 'hash.c', line 3055
VALUE rb_hash_empty_p(VALUE hash) { return RBOOL(RHASH_EMPTY_P(hash)); }
Instance Method Details
#<(other_hash) ⇒ Boolean
Returns true
if the entries of self
are a proper subset of the entries of other_hash
, false
otherwise:
h = {foo: 0, bar: 1}
h < {foo: 0, bar: 1, baz: 2} # => true # Proper subset.
h < {baz: 2, bar: 1, foo: 0} # => true # Order may differ.
h < h # => false # Not a proper subset.
h < {bar: 1, foo: 0} # => false # Not a proper subset.
h < {foo: 0, bar: 1, baz: 2} # => false # Different key.
h < {foo: 0, bar: 1, baz: 2} # => false # Different value.
See Hash
Inclusion.
Raises TypeError if other_hash
is not a hash and cannot be converted to a hash.
Related: see Methods for Comparing.
# File 'hash.c', line 4968
static VALUE rb_hash_lt(VALUE hash, VALUE other) { other = to_hash(other); if (RHASH_SIZE(hash) >= RHASH_SIZE(other)) return Qfalse; return hash_le(hash, other); }
#<=(other_hash) ⇒ Boolean
Returns true
if the entries of self
are a subset of the entries of other_hash
, false
otherwise:
h0 = {foo: 0, bar: 1}
h1 = {foo: 0, bar: 1, baz: 2}
h0 <= h0 # => true
h0 <= h1 # => true
h1 <= h0 # => false
See Hash
Inclusion.
Raises TypeError if other_hash
is not a hash and cannot be converted to a hash.
Related: see Methods for Comparing.
# File 'hash.c', line 4939
static VALUE rb_hash_le(VALUE hash, VALUE other) { other = to_hash(other); if (RHASH_SIZE(hash) > RHASH_SIZE(other)) return Qfalse; return hash_le(hash, other); }
#==(object) ⇒ Boolean
Returns whether self
and object
are equal.
Returns true
if all of the following are true:
-
object
is aHash
object (or can be converted to one). -
self
andobject
have the same keys (regardless of order). -
For each key #key,
self[key] == object[key]
.
Otherwise, returns false
.
Examples:
h = {foo: 0, bar: 1}
h == {foo: 0, bar: 1} # => true # Equal entries (same order)
h == {bar: 1, foo: 0} # => true # Equal entries (different order).
h == 1 # => false # Object not a hash.
h == {} # => false # Different number of entries.
h == {foo: 0, bar: 1} # => false # Different key.
h == {foo: 0, bar: 1} # => false # Different value.
Related: see Methods for Comparing.
# File 'hash.c', line 4035
static VALUE rb_hash_equal(VALUE hash1, VALUE hash2) { return hash_equal(hash1, hash2, FALSE); }
#>(other_hash) ⇒ Boolean
Returns true
if the entries of self
are a proper superset of the entries of other_hash
, false
otherwise:
h = {foo: 0, bar: 1, baz: 2}
h > {foo: 0, bar: 1} # => true # Proper superset.
h > {bar: 1, foo: 0} # => true # Order may differ.
h > h # => false # Not a proper superset.
h > {baz: 2, bar: 1, foo: 0} # => false # Not a proper superset.
h > {foo: 0, bar: 1} # => false # Different key.
h > {foo: 0, bar: 1} # => false # Different value.
See Hash
Inclusion.
Raises TypeError if other_hash
is not a hash and cannot be converted to a hash.
Related: see Methods for Comparing.
# File 'hash.c', line 5024
static VALUE rb_hash_gt(VALUE hash, VALUE other) { other = to_hash(other); if (RHASH_SIZE(hash) <= RHASH_SIZE(other)) return Qfalse; return hash_le(other, hash); }
#>=(other_hash) ⇒ Boolean
Returns true
if the entries of self
are a superset of the entries of other_hash
, false
otherwise:
h0 = {foo: 0, bar: 1, baz: 2}
h1 = {foo: 0, bar: 1}
h0 >= h1 # => true
h0 >= h0 # => true
h1 >= h0 # => false
See Hash
Inclusion.
Raises TypeError if other_hash
is not a hash and cannot be converted to a hash.
Related: see Methods for Comparing.
# File 'hash.c', line 4995
static VALUE rb_hash_ge(VALUE hash, VALUE other) { other = to_hash(other); if (RHASH_SIZE(hash) < RHASH_SIZE(other)) return Qfalse; return hash_le(other, hash); }
#[](key) ⇒ Object
Searches for a hash key equivalent to the given #key; see Hash
Key Equivalence.
If the key is found, returns its value:
{foo: 0, bar: 1, baz: 2}
h[: ] # => 1
Otherwise, returns a default value (see Hash
Default).
Related: #[]=; see also Methods for Fetching.
# File 'hash.c', line 2098
VALUE rb_hash_aref(VALUE hash, VALUE key) { st_data_t val; if (hash_stlike_lookup(hash, key, &val)) { return (VALUE)val; } else { return rb_hash_default_value(hash, key); } }
#[]=(key, object) ⇒ Object Also known as: #store
Associates the given object
with the given #key; returns object
.
Searches for a hash key equivalent to the given #key; see Hash
Key Equivalence.
If the key is found, replaces its value with the given object
; the ordering is not affected (see Entry Order):
h = {foo: 0, bar: 1}
h[:foo] = 2 # => 2
h[:foo] # => 2
If #key is not found, creates a new entry for the given #key and object
; the new entry is last in the order (see Entry Order):
h = {foo: 0, bar: 1}
h[:baz] = 2 # => 2
h[:baz] # => 2
h # => {:foo=>0, :bar=>1, :baz=>2}
Related: #[]; see also Methods for Assigning.
# File 'hash.c', line 2959
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val) { bool iter_p = hash_iterating_p(hash); rb_hash_modify(hash); if (!RHASH_STRING_KEY_P(hash, key)) { RHASH_UPDATE_ITER(hash, iter_p, key, hash_aset, val); } else { RHASH_UPDATE_ITER(hash, iter_p, key, hash_aset_str, val); } return val; }
#any? ⇒ Boolean
#any?(entry) ⇒ Boolean
#any? {|key, value| ... } ⇒ Boolean
Boolean
#any?(entry) ⇒ Boolean
#any? {|key, value| ... } ⇒ Boolean
Returns true
if any element satisfies a given criterion; false
otherwise.
If self
has no element, returns false
and argument or block are not used; otherwise behaves as below.
With no argument and no block, returns true
if self
is non-empty, false
otherwise.
With argument entry
and no block, returns true
if for any key #key self.assoc(key) == entry
, false
otherwise:
h = {foo: 0, bar: 1, baz: 2}
h.assoc(: ) # => [:bar, 1]
h.any?([:, 1]) # => true
h.any?([:, 0]) # => false
With no argument and a block given, calls the block with each key-value pair; returns true
if the block returns a truthy value, false
otherwise:
h = {foo: 0, bar: 1, baz: 2}
h.any? {|key, value| value < 3 } # => true
h.any? {|key, value| value > 3 } # => false
With both argument entry
and a block given, issues a warning and ignores the block.
Related: Enumerable#any? (which this method overrides); see also Methods for Fetching.
# File 'hash.c', line 4826
static VALUE rb_hash_any_p(int argc, VALUE *argv, VALUE hash) { VALUE args[2]; args[0] = Qfalse; rb_check_arity(argc, 0, 1); if (RHASH_EMPTY_P(hash)) return Qfalse; if (argc) { if (rb_block_given_p()) { rb_warn("given block not used"); } args[1] = argv[0]; rb_hash_foreach(hash, any_p_i_pattern, (VALUE)args); } else { if (!rb_block_given_p()) { /* yields pairs, never false */ return Qtrue; } if (rb_block_pair_yield_optimizable()) rb_hash_foreach(hash, any_p_i_fast, (VALUE)args); else rb_hash_foreach(hash, any_p_i, (VALUE)args); } return args[0]; }
#assoc(key) ⇒ entry
?
If the given #key is found, returns its entry as a 2-element array containing that key and its value:
h = {foo: 0, bar: 1, baz: 2}
h.assoc(: ) # => [:bar, 1]
Returns nil
if the key is not found.
Related: see Methods for Fetching.
# File 'hash.c', line 4423
static VALUE rb_hash_assoc(VALUE hash, VALUE key) { VALUE args[2]; if (RHASH_EMPTY_P(hash)) return Qnil; if (RHASH_ST_TABLE_P(hash) && !RHASH_IDENTHASH_P(hash)) { VALUE value = Qundef; st_table assoctable = *RHASH_ST_TABLE(hash); assoctable.type = &(struct st_hash_type){ .compare = assoc_cmp, .hash = assoctable.type->hash, }; VALUE arg = (VALUE)&(struct assoc_arg){ .tbl = &assoctable, .key = (st_data_t)key, }; if (RB_OBJ_FROZEN(hash)) { value = assoc_lookup(arg); } else { hash_iter_lev_inc(hash); value = rb_ensure(assoc_lookup, arg, hash_foreach_ensure, hash); } hash_verify(hash); if (!UNDEF_P(value)) return rb_assoc_new(key, value); } args[0] = key; args[1] = Qnil; rb_hash_foreach(hash, assoc_i, (VALUE)args); return args[1]; }
#clear ⇒ self
Removes all entries from self
; returns emptied self
.
Related: see Methods for Deleting.
# File 'hash.c', line 2881
VALUE rb_hash_clear(VALUE hash) { rb_hash_modify_check(hash); if (hash_iterating_p(hash)) { rb_hash_foreach(hash, clear_i, 0); } else if (RHASH_AR_TABLE_P(hash)) { ar_clear(hash); } else { st_clear(RHASH_ST_TABLE(hash)); compact_after_delete(hash); } return hash; }
#compact ⇒ Hash
Returns a copy of self
with all nil
-valued entries removed:
h = {foo: 0, bar: nil, baz: 2, bat: nil}
h.compact # => {foo: 0, baz: 2}
Related: see Methods for Deleting.
# File 'hash.c', line 4600
static VALUE rb_hash_compact(VALUE hash) { VALUE result = rb_hash_dup(hash); if (!RHASH_EMPTY_P(hash)) { rb_hash_foreach(result, delete_if_nil, result); compact_after_delete(result); } else if (rb_hash_compare_by_id_p(hash)) { result = rb_hash_compare_by_id(result); } return result; }
#compact! ⇒ self
?
If self
contains any nil
-valued entries, returns self
with all nil
-valued entries removed; returns nil
otherwise:
h = {foo: 0, bar: nil, baz: 2, bat: nil}
h.compact!
h # => {foo: 0, baz: 2}
h.compact! # => nil
Related: see Methods for Deleting.
# File 'hash.c', line 4630
static VALUE rb_hash_compact_bang(VALUE hash) { st_index_t n; rb_hash_modify_check(hash); n = RHASH_SIZE(hash); if (n) { rb_hash_foreach(hash, delete_if_nil, hash); if (n != RHASH_SIZE(hash)) return hash; } return Qnil; }
#deconstruct_keys(keys)
# File 'hash.c', line 5061
static VALUE rb_hash_deconstruct_keys(VALUE hash, VALUE keys) { return hash; }
Returns the default value for the given #key. The returned value will be determined either by the default proc or by the default value. See Hash
Default.
With no argument, returns the current default value:
h = {}
h.default # => nil
If #key is given, returns the default value for #key, regardless of whether that key exists:
h = Hash.new { |hash, key| hash[key] = "No key #{key}"}
h[:foo] = "Hello"
h.default(:foo) # => "No key foo"
# File 'hash.c', line 2218
static VALUE rb_hash_default(int argc, VALUE *argv, VALUE hash) { VALUE ifnone; rb_check_arity(argc, 0, 1); ifnone = RHASH_IFNONE(hash); if (FL_TEST(hash, RHASH_PROC_DEFAULT)) { if (argc == 0) return Qnil; return call_default_proc(ifnone, hash, argv[0]); } return ifnone; }
#default=(value) ⇒ Object
Sets the default value to value
; returns value
:
h = {}
h.default # => nil
h.default = false # => false
h.default # => false
See Hash
Default.
# File 'hash.c', line 2245
VALUE rb_hash_set_default(VALUE hash, VALUE ifnone) { rb_hash_modify_check(hash); SET_DEFAULT(hash, ifnone); return ifnone; }
#delete(key) ⇒ value
?
#delete(key) {|key| ... } ⇒ Object
value
?
#delete(key) {|key| ... } ⇒ Object
If an entry for the given #key is found, deletes the entry and returns its associated value; otherwise returns nil
or calls the given block.
With no block given and #key found, deletes the entry and returns its value:
h = {foo: 0, bar: 1, baz: 2}
h.delete(: ) # => 1
h # => {foo: 0, baz: 2}
With no block given and #key not found, returns nil
.
With a block given and #key found, ignores the block, deletes the entry, and returns its value:
h = {foo: 0, bar: 1, baz: 2}
h.delete(:baz) { |key| raise 'Will never happen'} # => 2
h # => {foo: 0, bar: 1}
With a block given and #key not found, calls the block and returns the block’s return value:
h = {foo: 0, bar: 1, baz: 2}
h.delete(:nosuch) { |key| "Key #{key} not found" } # => "Key nosuch not found"
h # => {foo: 0, bar: 1, baz: 2}
Related: see Methods for Deleting.
# File 'hash.c', line 2431
static VALUE rb_hash_delete_m(VALUE hash, VALUE key) { VALUE val; rb_hash_modify_check(hash); val = rb_hash_delete_entry(hash, key); if (!UNDEF_P(val)) { compact_after_delete(hash); return val; } else { if (rb_block_given_p()) { return rb_yield(key); } else { return Qnil; } } }
#delete_if {|key, value| ... } ⇒ self
#delete_if ⇒ Enumerator
self
#delete_if ⇒ Enumerator
With a block given, calls the block with each key-value pair, deletes each entry for which the block returns a truthy value, and returns self
:
h = {foo: 0, bar: 1, baz: 2}
h.delete_if {|key, value| value > 0 } # => {foo: 0}
With no block given, returns a new ::Enumerator
.
Related: see Methods for Deleting.
# File 'hash.c', line 2556
VALUE rb_hash_delete_if(VALUE hash) { RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); rb_hash_modify_check(hash); if (!RHASH_TABLE_EMPTY_P(hash)) { rb_hash_foreach(hash, delete_if_i, hash); compact_after_delete(hash); } return hash; }
#dig(key, *identifiers) ⇒ Object
Finds and returns an object found in nested objects, as specified by #key and identifiers
.
The nested objects may be instances of various classes. See Dig Methods.
Nested hashes:
h = {foo: {bar: {baz: 2}}}
h.dig(:foo) # => {bar: {baz: 2}}
h.dig(:foo, : ) # => {baz: 2}
h.dig(:foo, :, :baz) # => 2
h.dig(:foo, :, :BAZ) # => nil
Nested hashes and arrays:
h = {foo: {bar: [:a, :b, :c]}}
h.dig(:foo, :, 2) # => :c
If no such object is found, returns the hash default:
h = {foo: {bar: [:a, :b, :c]}}
h.dig(:hello) # => nil
h.default_proc = -> (hash, _key) { hash }
h.dig(:hello, :world)
# => {:foo=>{:bar=>[:a, :b, :c]}}
Related: Methods for Fetching.
# File 'hash.c', line 4890
static VALUE rb_hash_dig(int argc, VALUE *argv, VALUE self) { rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS); self = rb_hash_aref(self, *argv); if (!--argc) return self; ++argv; return rb_obj_dig(argc, argv, self, Qnil); }
#each_pair {|key, value| ... } ⇒ self
#each_pair ⇒ Enumerator
Also known as: #each_pair
self
#each_pair ⇒ Enumerator
With a block given, calls the block with each key-value pair; returns self
:
h = {foo: 0, bar: 1, baz: 2}
h.each_pair {|key, value| puts "#{key}: #{value}"} # => {foo: 0, bar: 1, baz: 2}
Output:
foo: 0
: 1
baz: 2
With no block given, returns a new ::Enumerator
.
Related: see Methods for Iterating.
# File 'hash.c', line 3168
static VALUE rb_hash_each_pair(VALUE hash) { RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); if (rb_block_pair_yield_optimizable()) rb_hash_foreach(hash, each_pair_i_fast, 0); else rb_hash_foreach(hash, each_pair_i, 0); return hash; }
#each_key {|key| ... } ⇒ self
#each_key ⇒ Enumerator
self
#each_key ⇒ Enumerator
With a block given, calls the block with each key; returns self
:
h = {foo: 0, bar: 1, baz: 2}
h.each_key {|key| puts key } # => {foo: 0, bar: 1, baz: 2}
Output:
foo
baz
With no block given, returns a new ::Enumerator
.
Related: see Methods for Iterating.
# File 'hash.c', line 3122
static VALUE rb_hash_each_key(VALUE hash) { RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); rb_hash_foreach(hash, each_key_i, 0); return hash; }
#each_pair {|key, value| ... } ⇒ self
#each_pair ⇒ Enumerator
self
#each_pair ⇒ Enumerator
Alias for #each.
#each_value {|value| ... } ⇒ self
#each_value ⇒ Enumerator
self
#each_value ⇒ Enumerator
With a block given, calls the block with each value; returns self
:
h = {foo: 0, bar: 1, baz: 2}
h.each_value {|value| puts value } # => {foo: 0, bar: 1, baz: 2}
Output:
0
1
2
With no block given, returns a new ::Enumerator
.
Related: see Methods for Iterating.
# File 'hash.c', line 3088
static VALUE rb_hash_each_value(VALUE hash) { RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); rb_hash_foreach(hash, each_value_i, 0); return hash; }
#eql?(object) ⇒ Boolean
Returns true
if all of the following are true:
-
The given
object
is aHash
object. -
self
andobject
have the same keys (regardless of order). -
For each key #key,
self[key].eql?(object[key])
.
Otherwise, returns false
.
h1 = {foo: 0, bar: 1, baz: 2}
h2 = {foo: 0, bar: 1, baz: 2}
h1.eql? h2 # => true
h3 = {baz: 2, bar: 1, foo: 0}
h1.eql? h3 # => true
Related: see Methods for Querying.
# File 'hash.c', line 4062
static VALUE rb_hash_eql(VALUE hash1, VALUE hash2) { return hash_equal(hash1, hash2, TRUE); }
#except(*keys) ⇒ Hash
Returns a copy of self
that excludes entries for the given #keys; any #keys that are not found are ignored:
h = {foo:0, bar: 1, baz: 2} # => {:foo=>0, :bar=>1, :baz=>2}
h.except(:baz, :foo) # => {:bar=>1}
h.except(:, :nosuch) # => {:foo=>0, :baz=>2}
Related: see Methods for Deleting.
# File 'hash.c', line 2682
static VALUE rb_hash_except(int argc, VALUE *argv, VALUE hash) { int i; VALUE key, result; result = hash_dup_with_compare_by_id(hash); for (i = 0; i < argc; i++) { key = argv[i]; rb_hash_delete(result, key); } compact_after_delete(result); return result; }
With no block given, returns the value for the given #key, if found;
h = {foo: 0, bar: 1, baz: 2}
h.fetch(: ) # => 1
If the key is not found, returns default_value
, if given, or raises ::KeyError
otherwise:
h.fetch(:nosuch, :default) # => :default
h.fetch(:nosuch) # Raises KeyError.
With a block given, calls the block with #key and returns the block’s return value:
{}.fetch(:nosuch) {|key| "No key #{key}"} # => "No key nosuch"
Note that this method does not use the values of either #default or #default_proc.
Related: see Methods for Fetching.
# File 'hash.c', line 2156
static VALUE rb_hash_fetch_m(int argc, VALUE *argv, VALUE hash) { VALUE key; st_data_t val; long block_given; rb_check_arity(argc, 1, 2); key = argv[0]; block_given = rb_block_given_p(); if (block_given && argc == 2) { rb_warn("block supersedes default value argument"); } if (hash_stlike_lookup(hash, key, &val)) { return (VALUE)val; } else { if (block_given) { return rb_yield(key); } else if (argc == 1) { VALUE desc = rb_protect(rb_inspect, key, 0); if (NIL_P(desc)) { desc = rb_any_to_s(key); } desc = rb_str_ellipsize(desc, 65); rb_key_err_raise(rb_sprintf("key not found: %"PRIsVALUE, desc), hash, key); } else { return argv[1]; } } }
When all given #keys are found, returns a new array containing the values associated with the given #keys:
h = {foo: 0, bar: 1, baz: 2}
h.fetch_values(:baz, :foo) # => [2, 0]
When any given #keys are not found and a block is given, calls the block with each unfound key and uses the block’s return value as the value for that key:
h.fetch_values(:, :foo, :bad, :bam) {|key| key.to_s}
# => [1, 0, "bad", "bam"]
When any given #keys are not found and no block is given, raises ::KeyError
.
Related: see Methods for Fetching.
# File 'hash.c', line 2752
static VALUE rb_hash_fetch_values(int argc, VALUE *argv, VALUE hash) { VALUE result = rb_ary_new2(argc); long i; for (i=0; i<argc; i++) { rb_ary_push(result, rb_hash_fetch(hash, argv[i])); } return result; }
#select {|key, value| ... } ⇒ Hash
#select ⇒ Enumerator
Also known as: #select
Hash
#select ⇒ Enumerator
With a block given, calls the block with each entry’s key and value; returns a new hash whose entries are those for which the block returns a truthy value:
h = {foo: 0, bar: 1, baz: 2}
h.select {|key, value| value < 2 } # => {foo: 0, bar: 1}
With no block given, returns a new ::Enumerator
.
Related: see Methods for Deleting.
# File 'hash.c', line 2790
static VALUE rb_hash_select(VALUE hash) { VALUE result; RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); result = hash_dup_with_compare_by_id(hash); if (!RHASH_EMPTY_P(hash)) { rb_hash_foreach(result, keep_if_i, result); compact_after_delete(result); } return result; }
#select! {|key, value| ... } ⇒ self
?
#select! ⇒ Enumerator
Also known as: #select!
self
?
#select! ⇒ Enumerator
With a block given, calls the block with each entry’s key and value; removes from self
each entry for which the block returns false
or nil
.
Returns self
if any entries were removed, nil
otherwise:
h = {foo: 0, bar: 1, baz: 2}
h.select! {|key, value| value < 2 } # => {foo: 0, bar: 1}
h.select! {|key, value| value < 2 } # => nil
With no block given, returns a new ::Enumerator
.
Related: see Methods for Deleting.
# File 'hash.c', line 2824
static VALUE rb_hash_select_bang(VALUE hash) { st_index_t n; RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); rb_hash_modify_check(hash); n = RHASH_SIZE(hash); if (!n) return Qnil; rb_hash_foreach(hash, keep_if_i, hash); if (n == RHASH_SIZE(hash)) return Qnil; return hash; }
#flatten(depth = 1) ⇒ Array
With positive integer depth
, returns a new array that is a recursive flattening of self
to the given depth
.
At each level of recursion:
-
Each element whose value is an array is “flattened” (that is, replaced by its individual array elements); see Array#flatten.
-
Each element whose value is not an array is unchanged. even if the value is an object that has instance method flatten (such as a hash).
Examples; note that entry foo: {bar: 1, baz: 2}
is never flattened.
h = {foo: {bar: 1, baz: 2}, bat: [:bam, [:bap, [:bah]]]}
h.flatten(1) # => [:foo, {:bar=>1, :baz=>2}, :bat, [:bam, [:bap, [:bah]]]]
h.flatten(2) # => [:foo, {:bar=>1, :baz=>2}, :bat, :bam, [:bap, [:bah]]]
h.flatten(3) # => [:foo, {:bar=>1, :baz=>2}, :bat, :bam, :bap, [:bah]]
h.flatten(4) # => [:foo, {:bar=>1, :baz=>2}, :bat, :bam, :bap, :bah]
h.flatten(5) # => [:foo, {:bar=>1, :baz=>2}, :bat, :bam, :bap, :bah]
With negative integer depth
, flattens all levels:
h.flatten(-1) # => [:foo, {:bar=>1, :baz=>2}, :bat, :bam, :bap, :bah]
With depth
zero, returns the equivalent of #to_a:
h.flatten(0) # => [[:foo, {:bar=>1, :baz=>2}], [:bat, [:bam, [:bap, [:bah]]]]]
Related: see Methods for Converting.
# File 'hash.c', line 4546
static VALUE rb_hash_flatten(int argc, VALUE *argv, VALUE hash) { VALUE ary; rb_check_arity(argc, 0, 1); if (argc) { int level = NUM2INT(argv[0]); if (level == 0) return rb_hash_to_a(hash); ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2); rb_hash_foreach(hash, flatten_i, ary); level--; if (level > 0) { VALUE ary_flatten_level = INT2FIX(level); rb_funcallv(ary, id_flatten_bang, 1, &ary_flatten_level); } else if (level < 0) { /* flatten recursively */ rb_funcallv(ary, id_flatten_bang, 0, 0); } } else { ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2); rb_hash_foreach(hash, flatten_i, ary); } return ary; }
#freeze
# File 'hash.c', line 103
VALUE rb_hash_freeze(VALUE hash) { return rb_obj_freeze(hash); }
#key?(key) ⇒ Boolean
#has_key?(key) ⇒ Boolean
Boolean
#has_key?(key) ⇒ Boolean
Alias for #key?.
#value?(value) ⇒ Boolean
#has_value?(value) ⇒ Boolean
Boolean
#has_value?(value) ⇒ Boolean
Alias for #value?.
#hash ⇒ Integer
Returns the integer hash-code for the hash.
Two hashes have the same hash-code if their content is the same (regardless of order):
h1 = {foo: 0, bar: 1, baz: 2}
h2 = {baz: 2, bar: 1, foo: 0}
h2.hash == h1.hash # => true
h2.eql? h1 # => true
Related: see Methods for Querying.
# File 'hash.c', line 4097
static VALUE rb_hash_hash(VALUE hash) { st_index_t size = RHASH_SIZE(hash); st_index_t hval = rb_hash_start(size); hval = rb_hash_uint(hval, (st_index_t)rb_hash_hash); if (size) { rb_hash_foreach(hash, hash_i, (VALUE)&hval); } hval = rb_hash_end(hval); return ST2FIX(hval); }
#key?(key) ⇒ Boolean
#include?(key) ⇒ Boolean
Boolean
#include?(key) ⇒ Boolean
Alias for #key?.
#replace(other_hash) ⇒ self
#initialize_copy(other_hash) ⇒ self
self
#initialize_copy(other_hash) ⇒ self
Alias for #replace.
Alias for #to_s.
#invert ⇒ Hash
Returns a new hash with each key-value pair inverted:
h = {foo: 0, bar: 1, baz: 2}
h1 = h.invert
h1 # => {0=>:foo, 1=>:bar, 2=>:baz}
Overwrites any repeated new keys (see Entry Order):
h = {foo: 0, bar: 0, baz: 0}
h.invert # => {0=>:baz}
Related: see Methods for Transforming Keys and Values.
# File 'hash.c', line 4136
static VALUE rb_hash_invert(VALUE hash) { VALUE h = rb_hash_new_with_size(RHASH_SIZE(hash)); rb_hash_foreach(hash, rb_hash_invert_i, h); return h; }
#keep_if {|key, value| ... } ⇒ self
#keep_if ⇒ Enumerator
self
#keep_if ⇒ Enumerator
With a block given, calls the block for each key-value pair; retains the entry if the block returns a truthy value; otherwise deletes the entry; returns self
:
h = {foo: 0, bar: 1, baz: 2}
h.keep_if { |key, value| key.start_with?('b') } # => {bar: 1, baz: 2}
With no block given, returns a new ::Enumerator
.
Related: see Methods for Deleting.
# File 'hash.c', line 2855
static VALUE rb_hash_keep_if(VALUE hash) { RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); rb_hash_modify_check(hash); if (!RHASH_TABLE_EMPTY_P(hash)) { rb_hash_foreach(hash, keep_if_i, hash); } return hash; }
#key(value) ⇒ key?
Returns the key for the first-found entry with the given value
(see Entry Order):
h = {foo: 0, bar: 2, baz: 2}
h.key(0) # => :foo
h.key(2) # => :bar
Returns nil
if no such value is found.
Related: see Methods for Fetching.
# File 'hash.c', line 2337
static VALUE rb_hash_key(VALUE hash, VALUE value) { VALUE args[2]; args[0] = value; args[1] = Qnil; rb_hash_foreach(hash, key_i, (VALUE)args); return args[1]; }
#key?(key) ⇒ Boolean
Also known as: #include?, #member?, #has_key?
Returns whether #key is a key in self
:
h = {foo: 0, bar: 1, baz: 2}
h.include?(: ) # => true
h.include?(:BAR) # => false
Related: Methods for Querying.
# File 'hash.c', line 3889
VALUE rb_hash_has_key(VALUE hash, VALUE key) { return RBOOL(hash_stlike_lookup(hash, key, NULL)); }
#keys ⇒ Array
Returns a new array containing all keys in self
:
h = {foo: 0, bar: 1, baz: 2}
h.keys # => [:foo, :bar, :baz]
Related: see Methods for Fetching.
# File 'hash.c', line 3797
VALUE rb_hash_keys(VALUE hash) { st_index_t size = RHASH_SIZE(hash); VALUE keys = rb_ary_new_capa(size); if (size == 0) return keys; if (ST_DATA_COMPATIBLE_P(VALUE)) { RARRAY_PTR_USE(keys, ptr, { if (RHASH_AR_TABLE_P(hash)) { size = ar_keys(hash, ptr, size); } else { st_table *table = RHASH_ST_TABLE(hash); size = st_keys(table, ptr, size); } }); rb_gc_writebarrier_remember(keys); rb_ary_set_len(keys, size); } else { rb_hash_foreach(hash, keys_i, keys); } return keys; }
#length ⇒ Integer Also known as: #size
Returns the count of entries in self
:
{foo: 0, bar: 1, baz: 2}.size # => 3
Related: see Methods for Querying.
# File 'hash.c', line 3031
VALUE rb_hash_size(VALUE hash) { return INT2FIX(RHASH_SIZE(hash)); }
#key?(key) ⇒ Boolean
#member?(key) ⇒ Boolean
Boolean
#member?(key) ⇒ Boolean
Alias for #key?.
#merge(*other_hashes) ⇒ Hash
#merge(*other_hashes) {|key, old_value, new_value| ... } ⇒ Hash
Hash
#merge(*other_hashes) {|key, old_value, new_value| ... } ⇒ Hash
Each argument other_hash
in other_hashes
must be a hash.
With arguments other_hashes
given and no block, returns the new hash formed by merging each successive other_hash
into a copy of self
; returns that copy; for each successive entry in other_hash
:
-
For a new key, the entry is added at the end of
self
. -
For duplicate key, the entry overwrites the entry in
self
, whose position is unchanged.
Example:
h = {foo: 0, bar: 1, baz: 2}
h1 = {bat: 3, bar: 4}
h2 = {bam: 5, bat:6}
h.merge(h1, h2) # => {foo: 0, bar: 4, baz: 2, bat: 6, bam: 5}
With arguments other_hashes
and a block given, behaves as above except that for a duplicate key the overwriting entry takes it value not from the entry in other_hash
, but instead from the block:
-
The block is called with the duplicate key and the values from both
self
andother_hash
. -
The block’s return value becomes the new value for the entry in
self
.
Example:
h = {foo: 0, bar: 1, baz: 2}
h1 = {bat: 3, bar: 4}
h2 = {bam: 5, bat:6}
h.merge(h1, h2) { |key, old_value, new_value| old_value + new_value }
# => {foo: 0, bar: 5, baz: 2, bat: 9, bam: 5}
With no arguments, returns a copy of self
; the block, if given, is ignored.
Related: see Methods for Assigning.
# File 'hash.c', line 4370
static VALUE rb_hash_merge(int argc, VALUE *argv, VALUE self) { return rb_hash_update(argc, argv, copy_compare_by_id(rb_hash_dup(self), self)); }
#update(*other_hashes) ⇒ self
#update(*other_hashes) {|key, old_value, new_value| ... } ⇒ self
Also known as: #update
self
#update(*other_hashes) {|key, old_value, new_value| ... } ⇒ self
Updates values and/or adds entries to self
; returns self
.
Each argument other_hash
in other_hashes
must be a hash.
With no block given, for each successive entry key+/+new_value
in each successive other_hash
:
-
If #key is in
self
, setsself[key] = new_value
, whose position is unchanged:h0 = {foo: 0, bar: 1, baz: 2} h1 = {bar: 3, foo: -1} h0.update(h1) # => {foo: -1, bar: 3, baz: 2}
-
If #key is not in
self
, adds the entry at the end ofself
:h = {foo: 0, bar: 1, baz: 2} h.update({bam: 3, bah: 4}) # => {foo: 0, bar: 1, baz: 2, bam: 3, bah: 4}
With a block given, for each successive entry key+/+new_value
in each successive other_hash
:
-
If #key is in
self
, fetchesold_value
fromself[key]
, calls the block with #key,old_value
, andnew_value
, and setsself[key] = new_value
, whose position is unchanged :season = {AB: 75, H: 20, HR: 3, SO: 17, W: 11, HBP: 3} today = {AB: 3, H: 1, W: 1} yesterday = {AB: 4, H: 2, HR: 1} season.update(yesterday, today) {|key, old_value, new_value| old_value + new_value } # => {AB: 82, H: 23, HR: 4, SO: 17, W: 12, HBP: 3}
-
If #key is not in
self
, adds the entry at the end ofself
:h = {foo: 0, bar: 1, baz: 2} h.update({bat: 3}) { fail 'Cannot happen' } # => {foo: 0, bar: 1, baz: 2, bat: 3}
Related: see Methods for Assigning.
# File 'hash.c', line 4259
static VALUE rb_hash_update(int argc, VALUE *argv, VALUE self) { struct update_call_args args = { .hash = self, .argv = argv, .argc = argc, .block_given = rb_block_given_p(), .iterating = false, }; VALUE arg = (VALUE)&args; rb_hash_modify(self); return rb_ensure(rb_hash_update_call, arg, rb_hash_update_ensure, arg); }
#rassoc(value) ⇒ Array?
Searches self
for the first entry whose value is #== to the given value
; see Entry Order.
If the entry is found, returns its key and value as a 2-element array; returns nil
if not found:
h = {foo: 0, bar: 1, baz: 1}
h.rassoc(1) # => [:bar, 1]
Related: see Methods for Fetching.
# File 'hash.c', line 4487
static VALUE rb_hash_rassoc(VALUE hash, VALUE obj) { VALUE args[2]; args[0] = obj; args[1] = Qnil; rb_hash_foreach(hash, rassoc_i, (VALUE)args); return args[1]; }
#rehash ⇒ self
Rebuilds the hash table for self
by recomputing the hash index for each key; returns self
. Calling this method ensures that the hash table is valid.
The hash table becomes invalid if the hash value of a key has changed after the entry was created. See Modifying an Active Hash Key.
# File 'hash.c', line 1989
VALUE rb_hash_rehash(VALUE hash) { VALUE tmp; st_table *tbl; if (hash_iterating_p(hash)) { rb_raise(rb_eRuntimeError, "rehash during iteration"); } rb_hash_modify_check(hash); if (RHASH_AR_TABLE_P(hash)) { tmp = hash_alloc(0); rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp); hash_ar_free_and_clear_table(hash); ar_copy(hash, tmp); } else if (RHASH_ST_TABLE_P(hash)) { st_table *old_tab = RHASH_ST_TABLE(hash); tmp = hash_alloc(0); hash_st_table_init(tmp, old_tab->type, old_tab->num_entries); tbl = RHASH_ST_TABLE(tmp); rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp); hash_st_free(hash); RHASH_ST_TABLE_SET(hash, tbl); RHASH_ST_CLEAR(tmp); } hash_verify(hash); return hash; }
#reject {|key, value| ... } ⇒ Hash
#reject ⇒ Enumerator
Hash
#reject ⇒ Enumerator
With a block given, returns a copy of self
with zero or more entries removed; calls the block with each key-value pair; excludes the entry in the copy if the block returns a truthy value, includes it otherwise:
h = {foo: 0, bar: 1, baz: 2}
h.reject {|key, value| key.start_with?('b') }
# => {foo: 0}
With no block given, returns a new ::Enumerator
.
Related: see Methods for Deleting.
# File 'hash.c', line 2620
static VALUE rb_hash_reject(VALUE hash) { VALUE result; RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); result = hash_dup_with_compare_by_id(hash); if (!RHASH_EMPTY_P(hash)) { rb_hash_foreach(result, delete_if_i, result); compact_after_delete(result); } return result; }
#reject! {|key, value| ... } ⇒ self
?
#reject! ⇒ Enumerator
self
?
#reject! ⇒ Enumerator
With a block given, calls the block with each entry’s key and value; removes the entry from self
if the block returns a truthy value.
Return self
if any entries were removed, nil
otherwise:
h = {foo: 0, bar: 1, baz: 2}
h.reject! {|key, value| value < 2 } # => {baz: 2}
h.reject! {|key, value| value < 2 } # => nil
With no block given, returns a new ::Enumerator
.
Related: see Methods for Deleting.
# File 'hash.c', line 2587
static VALUE rb_hash_reject_bang(VALUE hash) { st_index_t n; RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); rb_hash_modify(hash); n = RHASH_SIZE(hash); if (!n) return Qnil; rb_hash_foreach(hash, delete_if_i, hash); if (n == RHASH_SIZE(hash)) return Qnil; return hash; }
#replace(other_hash) ⇒ self
Also known as: #initialize_copy
Replaces the entire contents of self
with the contents of other_hash
; returns self
:
h = {foo: 0, bar: 1, baz: 2}
h.replace({bat: 3, bam: 4}) # => {bat: 3, bam: 4}
Also replaces the default value or proc of self
with the default value or proc of other_hash
.
h = {}
other = Hash.new(:ok)
h.replace(other)
h.default # => :ok
Related: see Methods for Assigning.
# File 'hash.c', line 2996
static VALUE rb_hash_replace(VALUE hash, VALUE hash2) { rb_hash_modify_check(hash); if (hash == hash2) return hash; if (hash_iterating_p(hash)) { rb_raise(rb_eRuntimeError, "can't replace hash during iteration"); } hash2 = to_hash(hash2); COPY_DEFAULT(hash, hash2); if (RHASH_AR_TABLE_P(hash)) { hash_ar_free_and_clear_table(hash); } else { hash_st_free_and_clear_table(hash); } hash_copy(hash, hash2); return hash; }
#select {|key, value| ... } ⇒ Hash
#select ⇒ Enumerator
Hash
#select ⇒ Enumerator
Alias for #filter.
#select! {|key, value| ... } ⇒ self
?
#select! ⇒ Enumerator
self
?
#select! ⇒ Enumerator
Alias for #filter!.
#shift ⇒ Array, value
Removes and returns the first entry of self
as a 2-element array; see Entry Order:
h = {foo: 0, bar: 1, baz: 2}
h.shift # => [:foo, 0]
h # => {bar: 1, baz: 2}
Returns nil
if self
is empty.
Related: see Methods for Deleting.
# File 'hash.c', line 2484
static VALUE rb_hash_shift(VALUE hash) { struct shift_var var; rb_hash_modify_check(hash); if (RHASH_AR_TABLE_P(hash)) { var.key = Qundef; if (!hash_iterating_p(hash)) { if (ar_shift(hash, &var.key, &var.val)) { return rb_assoc_new(var.key, var.val); } } else { rb_hash_foreach(hash, shift_i_safe, (VALUE)&var); if (!UNDEF_P(var.key)) { rb_hash_delete_entry(hash, var.key); return rb_assoc_new(var.key, var.val); } } } if (RHASH_ST_TABLE_P(hash)) { var.key = Qundef; if (!hash_iterating_p(hash)) { if (st_shift(RHASH_ST_TABLE(hash), &var.key, &var.val)) { return rb_assoc_new(var.key, var.val); } } else { rb_hash_foreach(hash, shift_i_safe, (VALUE)&var); if (!UNDEF_P(var.key)) { rb_hash_delete_entry(hash, var.key); return rb_assoc_new(var.key, var.val); } } } return Qnil; }
Alias for #length.
#slice(*keys) ⇒ Hash
Returns a new hash containing the entries from self
for the given #keys; ignores any keys that are not found:
h = {foo: 0, bar: 1, baz: 2}
h.slice(:baz, :foo, :nosuch) # => {baz: 2, foo: 0}
Related: see Methods for Deleting.
# File 'hash.c', line 2647
static VALUE rb_hash_slice(int argc, VALUE *argv, VALUE hash) { int i; VALUE key, value, result; if (argc == 0 || RHASH_EMPTY_P(hash)) { return copy_compare_by_id(rb_hash_new(), hash); } result = copy_compare_by_id(rb_hash_new_with_size(argc), hash); for (i = 0; i < argc; i++) { key = argv[i]; value = rb_hash_lookup2(hash, key, Qundef); if (!UNDEF_P(value)) rb_hash_aset(result, key, value); } return result; }
Alias for #[]=.
#to_a ⇒ Array
Returns all elements of self
as an array of 2-element arrays; each nested array contains a key-value pair from self
:
h = {foo: 0, bar: 1, baz: 2}
h.to_a # => [[:foo, 0], [:bar, 1], [:baz, 2]]
Related: see Methods for Converting.
# File 'hash.c', line 3589
static VALUE rb_hash_to_a(VALUE hash) { VALUE ary; ary = rb_ary_new_capa(RHASH_SIZE(hash)); rb_hash_foreach(hash, to_a_i, ary); return ary; }
#to_h {|key, value| ... } ⇒ Hash
#to_h ⇒ self
, Hash
Hash
#to_h ⇒ self
, Hash
With a block given, returns a new hash whose content is based on the block; the block is called with each entry’s key and value; the block should return a 2-element array containing the key and value to be included in the returned array:
h = {foo: 0, bar: 1, baz: 2}
h.to_h {|key, value| [value, key] }
# => {0 => :foo, 1 => :bar, 2 => :baz}
With no block given, returns self
if self
is an instance of Hash
; if self
is a subclass of Hash
, returns a new hash containing the content of self
.
Related: see Methods for Converting.
# File 'hash.c', line 3765
static VALUE rb_hash_to_h(VALUE hash) { if (rb_block_given_p()) { return rb_hash_to_h_block(hash); } if (rb_obj_class(hash) != rb_cHash) { const VALUE flags = RBASIC(hash)->flags; hash = hash_dup(hash, rb_cHash, flags & RHASH_PROC_DEFAULT); } return hash; }
#to_hash ⇒ self
Returns self
.
Related: see Methods for Converting.
# File 'hash.c', line 3706
static VALUE rb_hash_to_hash(VALUE hash) { return hash; }
#to_proc ⇒ Proc
Returns a ::Proc
object that maps a key to its value:
h = {foo: 0, bar: 1, baz: 2}
proc = h.to_proc
proc.class # => Proc
proc.call(:foo) # => 0
proc.call(: ) # => 1
proc.call(:nosuch) # => nil
Related: see Methods for Converting.
# File 'hash.c', line 5054
static VALUE rb_hash_to_proc(VALUE hash) { return rb_func_lambda_new(hash_proc_call, hash, 1, 1); }
#to_s ⇒ String Also known as: #inspect
Returns a new string containing the hash entries:
h = {foo: 0, bar: 1, baz: 2}
h.inspect # => "{foo: 0, bar: 1, baz: 2}"
Related: see Methods for Converting.
# File 'hash.c', line 3690
static VALUE rb_hash_inspect(VALUE hash) { if (RHASH_EMPTY_P(hash)) return rb_usascii_str_new2("{}"); return rb_exec_recursive(inspect_hash, hash, 0); }
#transform_keys {|old_key| ... } ⇒ Hash
#transform_keys(other_hash) ⇒ Hash
#transform_keys(other_hash) {|old_key| ... } ⇒ Hash
#transform_keys ⇒ Enumerator
Hash
#transform_keys(other_hash) ⇒ Hash
#transform_keys(other_hash) {|old_key| ... } ⇒ Hash
#transform_keys ⇒ Enumerator
With an argument, a block, or both given, derives a new hash new_hash
from self
, the argument, and/or the block; all, some, or none of its keys may be different from those in self
.
With a block given and no argument, new_hash
has keys determined only by the block.
For each key/value pair old_key/value
in self
, calls the block with old_key
; the block’s return value becomes new_key
; sets new_hash[new_key] = value
; a duplicate key overwrites:
h = {foo: 0, bar: 1, baz: 2}
h.transform_keys {|old_key| old_key.to_s }
# => {"foo" => 0, "bar" => 1, "baz" => 2}
h.transform_keys {|old_key| 'xxx' }
# => {"xxx" => 2}
With argument other_hash
given and no block, new_hash
may have new keys provided by other_hash
and unchanged keys provided by self
.
For each key/value pair old_key/old_value
in self
, looks for key old_key
in other_hash
:
-
If
old_key
is found, its valueother_hash[old_key]
is taken asnew_key
; setsnew_hash[new_key] = value
; a duplicate key overwrites:h = {foo: 0, bar: 1, baz: 2} h.transform_keys(baz: :BAZ, bar: :BAR, foo: :FOO) # => {FOO: 0, BAR: 1, BAZ: 2} h.transform_keys(baz: :FOO, bar: :FOO, foo: :FOO) # => {FOO: 2}
-
If
old_key
is not found, setsnew_hash[old_key] = value
; a duplicate key overwrites:h = {foo: 0, bar: 1, baz: 2} h.transform_keys({}) # => {foo: 0, bar: 1, baz: 2} h.transform_keys(baz: :foo) # => {foo: 2, bar: 1}
Unused keys in other_hash
are ignored:
h = {foo: 0, bar: 1, baz: 2}
h.transform_keys(bat: 3)
# => {foo: 0, bar: 1, baz: 2}
With both argument other_hash
and a block given, new_hash
has new keys specified by other_hash
or by the block, and unchanged keys provided by self
.
For each pair old_key
and value
in self
:
-
If
other_hash
has keyold_key
(with valuenew_key
), does not call the block for that key; setsnew_hash[new_key] = value
; a duplicate key overwrites:h = {foo: 0, bar: 1, baz: 2} h.transform_keys(baz: :BAZ, bar: :BAR, foo: :FOO) {|key| fail 'Not called' } # => {FOO: 0, BAR: 1, BAZ: 2}
-
If
other_hash
does not have keyold_key
, calls the block withold_key
and takes its return value asnew_key
; setsnew_hash[new_key] = value
; a duplicate key overwrites:h = {foo: 0, bar: 1, baz: 2} h.transform_keys(baz: :BAZ) {|key| key.to_s.reverse } # => {"oof" => 0, "rab" => 1, BAZ: 2} h.transform_keys(baz: :BAZ) {|key| 'ook' } # => {"ook" => 1, BAZ: 2}
With no argument and no block given, returns a new ::Enumerator
.
Related: see Methods for Transforming Keys and Values.
# File 'hash.c', line 3297
static VALUE rb_hash_transform_keys(int argc, VALUE *argv, VALUE hash) { VALUE result; struct transform_keys_args transarg = {0}; argc = rb_check_arity(argc, 0, 1); if (argc > 0) { transarg.trans = to_hash(argv[0]); transarg.block_given = rb_block_given_p(); } else { RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); } result = rb_hash_new(); if (!RHASH_EMPTY_P(hash)) { if (transarg.trans) { transarg.result = result; rb_hash_foreach(hash, transform_keys_hash_i, (VALUE)&transarg); } else { rb_hash_foreach(hash, transform_keys_i, result); } } return result; }
#transform_keys! {|old_key| ... } ⇒ self
#transform_keys!(other_hash) ⇒ self
#transform_keys!(other_hash) {|old_key| ... } ⇒ self
#transform_keys! ⇒ Enumerator
self
#transform_keys!(other_hash) ⇒ self
#transform_keys!(other_hash) {|old_key| ... } ⇒ self
#transform_keys! ⇒ Enumerator
With an argument, a block, or both given, derives keys from the argument, the block, and self
; all, some, or none of the keys in self
may be changed.
With a block given and no argument, derives keys only from the block; all, some, or none of the keys in self
may be changed.
For each key/value pair old_key/value
in self
, calls the block with old_key
; the block’s return value becomes new_key
; removes the entry for old_key
: self.delete(old_key)
; sets self[new_key] = value
; a duplicate key overwrites:
h = {foo: 0, bar: 1, baz: 2}
h.transform_keys! {|old_key| old_key.to_s }
# => {"foo" => 0, "bar" => 1, "baz" => 2}
h = {foo: 0, bar: 1, baz: 2}
h.transform_keys! {|old_key| 'xxx' }
# => {"xxx" => 2}
With argument other_hash
given and no block, derives keys for self
from other_hash
and self
; all, some, or none of the keys in self
may be changed.
For each key/value pair old_key/old_value
in self
, looks for key old_key
in other_hash
:
-
If
old_key
is found, takes valueother_hash[old_key]
asnew_key
; removes the entry forold_key
:self.delete(old_key)
; setsself[new_key] = value
; a duplicate key overwrites:h = {foo: 0, bar: 1, baz: 2} h.transform_keys!(baz: :BAZ, bar: :BAR, foo: :FOO) # => {FOO: 0, BAR: 1, BAZ: 2} h = {foo: 0, bar: 1, baz: 2} h.transform_keys!(baz: :FOO, bar: :FOO, foo: :FOO) # => {FOO: 2}
-
If
old_key
is not found, does nothing:h = {foo: 0, bar: 1, baz: 2} h.transform_keys!({}) # => {foo: 0, bar: 1, baz: 2} h.transform_keys!(baz: :foo) # => {foo: 2, bar: 1}
Unused keys in other_hash
are ignored:
h = {foo: 0, bar: 1, baz: 2}
h.transform_keys!(bat: 3)
# => {foo: 0, bar: 1, baz: 2}
With both argument other_hash
and a block given, derives keys from other_hash
, the block, and self
; all, some, or none of the keys in self
may be changed.
For each pair old_key
and value
in self
:
-
If
other_hash
has keyold_key
(with valuenew_key
), does not call the block for that key; removes the entry forold_key
:self.delete(old_key)
; setsself[new_key] = value
; a duplicate key overwrites:h = {foo: 0, bar: 1, baz: 2} h.transform_keys!(baz: :BAZ, bar: :BAR, foo: :FOO) {|key| fail 'Not called' } # => {FOO: 0, BAR: 1, BAZ: 2}
-
If
other_hash
does not have keyold_key
, calls the block withold_key
and takes its return value asnew_key
; removes the entry forold_key
:self.delete(old_key)
; setsself[new_key] = value
; a duplicate key overwrites:h = {foo: 0, bar: 1, baz: 2} h.transform_keys!(baz: :BAZ) {|key| key.to_s.reverse } # => {"oof" => 0, "rab" => 1, BAZ: 2} h = {foo: 0, bar: 1, baz: 2} h.transform_keys!(baz: :BAZ) {|key| 'ook' } # => {"ook" => 1, BAZ: 2}
With no argument and no block given, returns a new ::Enumerator
.
Related: see Methods for Transforming Keys and Values.
# File 'hash.c', line 3421
static VALUE rb_hash_transform_keys_bang(int argc, VALUE *argv, VALUE hash) { VALUE trans = 0; int block_given = 0; argc = rb_check_arity(argc, 0, 1); if (argc > 0) { trans = to_hash(argv[0]); block_given = rb_block_given_p(); } else { RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); } rb_hash_modify_check(hash); if (!RHASH_TABLE_EMPTY_P(hash)) { long i; VALUE new_keys = hash_alloc(0); VALUE pairs = rb_ary_hidden_new(RHASH_SIZE(hash) * 2); rb_hash_foreach(hash, flatten_i, pairs); for (i = 0; i < RARRAY_LEN(pairs); i += 2) { VALUE key = RARRAY_AREF(pairs, i), new_key, val; if (!trans) { new_key = rb_yield(key); } else if (!UNDEF_P(new_key = rb_hash_lookup2(trans, key, Qundef))) { /* use the transformed key */ } else if (block_given) { new_key = rb_yield(key); } else { new_key = key; } val = RARRAY_AREF(pairs, i+1); if (!hash_stlike_lookup(new_keys, key, NULL)) { rb_hash_stlike_delete(hash, &key, NULL); } rb_hash_aset(hash, new_key, val); rb_hash_aset(new_keys, new_key, Qnil); } rb_ary_clear(pairs); rb_hash_clear(new_keys); } compact_after_delete(hash); return hash; }
#transform_values {|value| ... } ⇒ Hash
#transform_values ⇒ Enumerator
Hash
#transform_values ⇒ Enumerator
With a block given, returns a new hash new_hash
; for each pair key+/+value
in self
, calls the block with value
and captures its return as new_value
; adds to new_hash
the entry key+/+new_value
:
h = {foo: 0, bar: 1, baz: 2}
h1 = h.transform_values {|value| value * 100}
h1 # => {foo: 0, bar: 100, baz: 200}
With no block given, returns a new ::Enumerator
.
Related: see Methods for Transforming Keys and Values.
# File 'hash.c', line 3518
static VALUE rb_hash_transform_values(VALUE hash) { VALUE result; RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); result = hash_dup_with_compare_by_id(hash); SET_DEFAULT(result, Qnil); if (!RHASH_EMPTY_P(hash)) { transform_values(result); compact_after_delete(result); } return result; }
#transform_values! {|old_value| ... } ⇒ self
#transform_values! ⇒ Enumerator
self
#transform_values! ⇒ Enumerator
With a block given, changes the values of self
as determined by the block; returns self
.
For each entry key+/+old_value
in self
, calls the block with old_value
, captures its return value as new_value
, and sets self[key] = new_value
:
h = {foo: 0, bar: 1, baz: 2}
h.transform_values! {|value| value * 100} # => {foo: 0, bar: 100, baz: 200}
With no block given, returns a new ::Enumerator
.
Related: see Methods for Transforming Keys and Values.
# File 'hash.c', line 3556
static VALUE rb_hash_transform_values_bang(VALUE hash) { RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); rb_hash_modify_check(hash); if (!RHASH_TABLE_EMPTY_P(hash)) { transform_values(hash); } return hash; }
#update(*other_hashes) ⇒ self
#update(*other_hashes) {|key, old_value, new_value| ... } ⇒ self
self
#update(*other_hashes) {|key, old_value, new_value| ... } ⇒ self
Alias for #merge!.
#value?(value) ⇒ Boolean
Also known as: #has_value?
Returns whether value
is a value in self
.
Related: Methods for Querying.
# File 'hash.c', line 3916
static VALUE rb_hash_has_value(VALUE hash, VALUE val) { VALUE data[2]; data[0] = Qfalse; data[1] = val; rb_hash_foreach(hash, rb_hash_search_value, (VALUE)data); return data[0]; }
#values ⇒ Array
Returns a new array containing all values in self
:
h = {foo: 0, bar: 1, baz: 2}
h.values # => [0, 1, 2]
Related: see Methods for Fetching.
# File 'hash.c', line 3844
VALUE rb_hash_values(VALUE hash) { VALUE values; st_index_t size = RHASH_SIZE(hash); values = rb_ary_new_capa(size); if (size == 0) return values; if (ST_DATA_COMPATIBLE_P(VALUE)) { if (RHASH_AR_TABLE_P(hash)) { rb_gc_writebarrier_remember(values); RARRAY_PTR_USE(values, ptr, { size = ar_values(hash, ptr, size); }); } else if (RHASH_ST_TABLE_P(hash)) { st_table *table = RHASH_ST_TABLE(hash); rb_gc_writebarrier_remember(values); RARRAY_PTR_USE(values, ptr, { size = st_values(table, ptr, size); }); } rb_ary_set_len(values, size); } else { rb_hash_foreach(hash, values_i, values); } return values; }
#values_at(*keys) ⇒ Array
Returns a new array containing values for the given #keys:
h = {foo: 0, bar: 1, baz: 2}
h.values_at(:baz, :foo) # => [2, 0]
The hash default is returned for each key that is not found:
h.values_at(:hello, :foo) # => [nil, 0]
Related: see Methods for Fetching.
# File 'hash.c', line 2716
static VALUE rb_hash_values_at(int argc, VALUE *argv, VALUE hash) { VALUE result = rb_ary_new2(argc); long i; for (i=0; i<argc; i++) { rb_ary_push(result, rb_hash_aref(hash, argv[i])); } return result; }