# class Hash(K, V)

- Hash(K, V)
- Reference
- Object

##
Overview

A `Hash` represents a collection of key-value mappings, similar to a dictionary.

Main operations are storing a key-value mapping (`#[]=`) and querying the value associated to a key (`#[]`). Key-value mappings can also be deleted (`#delete`). Keys are unique within a hash. When adding a key-value mapping with a key that is already in use, the old value will be forgotten.

    # Create a new Hash for mapping String to Int32
    hash = Hash(String, Int32).new
    hash["one"] = 1
    hash["two"] = 2
    hash["one"] # => 1

Hash literals can also be used to create a `Hash`:

    {"one" => 1, "two" => 2}

Implementation is based on an open hash table. Two objects refer to the same hash key when their hash value (`Object#hash`) is identical and both objects are equal to each other (`Object#==`).

Enumeration follows the order that the corresponding keys were inserted.

NOTE When using mutable data types as keys, changing the value of a key after it was inserted into the `Hash` may lead to undefined behaviour. This can be restored by re-indexing the hash with `#rehash`.

##
Included Modules

- Enumerable({K, V})
- Iterable({K, V})

##
Defined in:

##
Constructors

- .new(default_value : V, initial_capacity = nil)

  Creates a new empty `Hash` where the default_value is returned if a key is missing.

- .new(ctx : YAML::ParseContext, node : YAML::Nodes::Node)
- .new(pull : JSON::PullParser)

  Reads a Hash from the given pull parser.

- .new

  Creates a new empty `Hash`.

- .new(block : Hash(K, V), K -> V? = nil, *, initial_capacity = nil)

  Creates a new empty `Hash` with a block for handling missing keys.

- .new(ctx : YAML::ParseContext, node : YAML::Nodes::Node, &)
- .new(initial_capacity = nil, &block : Hash(K, V), K -> V)

  Creates a new empty `Hash` with a block that handles missing keys.

##
Class Method Summary

- .zip(ary1 : Array(K), ary2 : Array(V))

  Zips two arrays into a `Hash`, taking keys from ary1 and values from ary2.

##
Instance Method Summary

- #==(other : YAML::Any)
- #==(other : JSON::Any)
- #==(other : Hash)

  Compares with other.

- #[](key)

  Returns the value for the key given by key.

- #[]=(key : K, value : V)

  Sets the value of key to the given value.

- #[]?(key)

  Returns the value for the key given by key.

- #clear

  Empties a `Hash` and returns it.

- #clone

  Similar to `#dup`, but duplicates the values as well.

- #compact

  Returns new `Hash` without `nil` values.

- #compact!

  Removes all `nil` value from `self`.

- #compare_by_identity

  Makes this hash compare keys using their object identity (`object_id)` for types that define such method (`Reference` types, but also structs that might wrap other `Reference` types and delegate the `object_id` method to them).

- #compare_by_identity?

  Returns `true` of this Hash is comparing keys by `object_id`.

- #delete(key, &)

  Deletes the key-value pair and returns the value, else yields key with given block.

- #delete(key)

  Deletes the key-value pair and returns the value, otherwise returns `nil`.

- #delete_if(&)

  Deletes each key-value pair for which the given block returns `true`.

- #dig(key : K, *subkeys)

  Traverses the depth of a structure and returns the value, otherwise raises `KeyError`.

- #dig?(key : K, *subkeys)

  Traverses the depth of a structure and returns the value.

- #dup

  Duplicates a `Hash`.

- #each

  Returns an iterator over the hash entries.

- #each(&) : Nil

  Calls the given block for each key-value pair and passes in the key and the value.

- #each_key(&)

  Calls the given block for each key-value pair and passes in the key.

- #each_key

  Returns an iterator over the hash keys.

- #each_value(&)

  Calls the given block for each key-value pair and passes in the value.

- #each_value

  Returns an iterator over the hash values.

- #empty?

  Returns `true` when hash contains no key-value pairs.

- #fetch(key, default)

  Returns the value for the key given by key, or when not found the value given by default.

- #fetch(key, &)

  Returns the value for the key given by key, or when not found calls the given block with the key.

- #first_key

  Returns the first key in the hash.

- #first_key?

  Returns the first key if it exists, or returns `nil`.

- #first_value

  Returns the first value in the hash.

- #first_value?

  Returns the first value if it exists, or returns `nil`.

- #has_key?(key)

  Returns `true` when key given by key exists, otherwise `false`.

- #has_value?(val)

  Returns `true` when value given by value exists, otherwise `false`.

- #hash(hasher)

  See `Object#hash(hasher)`

- #inspect(io : IO) : Nil

  Appends a String representation of this object which includes its class name, its object address and the values of all instance variables.

- #invert

  Inverts keys and values.

- #key_for(value)

  Returns a key with the given value, else raises `KeyError`.

- #key_for(value, &)

  Returns a key with the given value, else yields value with the given block.

- #key_for?(value)

  Returns a key with the given value, else `nil`.

- #key_index(key)

  Returns the index of the given key, or `nil` when not found.

- #keys : Array(K)

  Returns a new `Array` with all the keys.

- #last_key

  Returns the last key in the hash.

- #last_key?

  Returns the last key if it exists, or returns `nil`.

- #last_value

  Returns the last value in the hash.

- #last_value?

  Returns the last value if it exists, or returns `nil`.

- #merge(other : Hash(L, W), &block : K, V, W -> V | W) forall L, W
- #merge(other : Hash(L, W)) forall L, W

  Returns a new `Hash` with the keys and values of this hash and other combined.

- #merge!(other : Hash)

  Similar to `#merge`, but the receiver is modified.

- #merge!(other : Hash, &) : self

  Adds the contents of other to this hash.

- #pretty_print(pp) : Nil
- #put(key : K, value : V, &)

  Sets the value of key to the given value.

- #rehash : Nil

  Rebuilds the hash table based on the current value of each key.

- #reject(*keys)

  Returns a new `Hash` without the given keys.

- #reject(&block : K, V -> _)

  Returns a new hash consisting of entries for which the block returns `false`.

- #reject!(*keys)
- #reject!(keys : Array | Tuple)

  Removes a list of keys out of hash.

- #reject!(&block : K, V -> _)

  Equivalent to `Hash#reject`, but makes modification on the current object rather that returning a new one.

- #select(&block : K, V -> _)

  Returns a new hash consisting of entries for which the block returns `true`.

- #select(keys : Array | Tuple)

  Returns a new `Hash` with the given keys.

- #select(*keys)

  Returns a new `Hash` with the given keys.

- #select!(&block : K, V -> _)

  Equivalent to `Hash#select` but makes modification on the current object rather that returning a new one.

- #select!(*keys)

  Removes every element except the given ones.

- #select!(keys : Array | Tuple)

  Removes every element except the given ones.

- #shift

  Deletes and returns the first key-value pair in the hash, or raises `IndexError` if the hash is empty.

- #shift(&)

  Deletes and returns the first key-value pair in the hash.

- #shift?

  Same as `#shift`, but returns `nil` if the hash is empty.

- #size : Int32

  Returns the number of elements in this Hash.

- #to_a : Array(Tuple(K, V))

  Returns an array of tuples with key and values belonging to this Hash.

- #to_h

  Returns `self`.

- #to_json(json : JSON::Builder)

  Serializes this Hash into JSON.

- #to_s(io : IO) : Nil

  Converts to a `String`.

- #to_yaml(yaml : YAML::Nodes::Builder)
- #transform_keys(&block : K -> K2) forall K2

  Returns a new hash with all keys converted using the block operation.

- #transform_values(&block : V -> V2) forall V2

  Returns a new hash with the results of running block once for every value.

- #transform_values!(&block : V -> V)

  Destructively transforms all values using a block.

- #values : Array(V)

  Returns only the values as an `Array`.

- #values_at(*indexes : K)

  Returns a tuple populated with the elements at the given indexes.

### Instance methods inherited from module `Iterable({K, V})`

chunk(reuse = false, &block : {K, V} -> U) forall U chunk, chunk_while(reuse : Bool | Array({K, V}) = false, &block : {K, V}, {K, V} -> B) forall B chunk_while, cycle(n)
cycle cycle, each each, each_cons(count : Int, reuse = false) each_cons, each_slice(count : Int, reuse = false) each_slice, each_with_index(offset = 0) each_with_index, each_with_object(obj) each_with_object, slice_after(reuse : Bool | Array({K, V}) = false, &block : {K, V} -> B) forall B
slice_after(pattern, reuse : Bool | Array({K, V}) = false) slice_after, slice_before(reuse : Bool | Array({K, V}) = false, &block : {K, V} -> B) forall B
slice_before(pattern, reuse : Bool | Array({K, V}) = false) slice_before, slice_when(reuse : Bool | Array({K, V}) = false, &block : {K, V}, {K, V} -> B) forall B slice_when

### Instance methods inherited from module `Enumerable({K, V})`

all?(&)
all?(pattern)
all? all?, any?(&)
any?(pattern)
any? any?, chunks(&block : {K, V} -> U) forall U chunks, compact_map(&) compact_map, count(&)
count(item) count, cycle(n, &)
cycle(&) cycle, each(&block : {K, V} -> _) each, each_cons(count : Int, reuse = false, &) each_cons, each_cons_pair(& : {K, V}, {K, V} -> _) : Nil each_cons_pair, each_slice(count : Int, reuse = false, &) each_slice, each_with_index(offset = 0, &) each_with_index, each_with_object(obj, &) each_with_object, find(if_none = nil, &) find, first(count : Int)
first first, first? first?, flat_map(&block : {K, V} -> Array(U) | Iterator(U) | U) forall U flat_map, grep(pattern) grep, group_by(&block : {K, V} -> U) forall U group_by, in_groups_of(size : Int, filled_up_with : U = nil) forall U
in_groups_of(size : Int, filled_up_with : U = nil, reuse = false, &) forall U in_groups_of, includes?(obj) includes?, index(&)
index(obj) index, index_by(&block : {K, V} -> U) forall U index_by, join(separator = "", &)
join(separator, io, &)
join(separator, io)
join(separator = "") join, map(&block : {K, V} -> U) forall U map, map_with_index(offset = 0, &block : {K, V}, Int32 -> U) forall U map_with_index, max max, max? max?, max_by(&block : {K, V} -> U) forall U max_by, max_by?(&block : {K, V} -> U) forall U max_by?, max_of(&block : {K, V} -> U) forall U max_of, max_of?(&block : {K, V} -> U) forall U max_of?, min min, min? min?, min_by(&block : {K, V} -> U) forall U min_by, min_by?(&block : {K, V} -> U) forall U min_by?, min_of(&block : {K, V} -> U) forall U min_of, min_of?(&block : {K, V} -> U) forall U min_of?, minmax minmax, minmax? minmax?, minmax_by(&block : {K, V} -> U) forall U minmax_by, minmax_by?(&block : {K, V} -> U) forall U minmax_by?, minmax_of(&block : {K, V} -> U) forall U minmax_of, minmax_of?(&block : {K, V} -> U) forall U minmax_of?, none?
none?(pattern)
none?(&) none?, one?(&)
one?(pattern)
one? one?, partition(&) partition, product(&)
product(initial : Number, &)
product
product(initial : Number) product, reduce(memo, &)
reduce(&) reduce, reduce?(&) reduce?, reject(&block : {K, V} -> )
reject(type : U.class) forall U
reject(pattern) reject, select(pattern)
select(type : U.class) forall U
select(&block : {K, V} -> ) select, size size, skip(count : Int) skip, skip_while(&) skip_while, sum(initial)
sum
sum(initial, &)
sum(&) sum, take_while(&) take_while, tally : Hash({K, V}, Int32) tally, to_a to_a, to_h
to_h(&block : {K, V} -> Tuple(K, V)) forall K, V to_h, to_set to_set, zip(*others : Indexable | Iterable | Iterator, &)
zip(*others : Indexable | Iterable | Iterator) zip, zip?(*others : Indexable | Iterable | Iterator, &)
zip?(*others : Indexable | Iterable | Iterator) zip?

### Instance methods inherited from class `Reference`

==(other : self)
==(other : JSON::Any)
==(other : YAML::Any)
==(other) ==, dup dup, hash(hasher) hash, inspect(io : IO) : Nil inspect, object_id : UInt64 object_id, pretty_print(pp) : Nil pretty_print, same?(other : Reference)
same?(other : Nil) same?, to_s(io : IO) : Nil to_s

### Constructor methods inherited from class `Reference`

new new

### Instance methods inherited from class `Object`

!=(other) !=, !~(other) !~, ==(other) ==, ===(other : JSON::Any)
===(other : YAML::Any)
===(other) ===, =~(other) =~, __crystal_pseudo_! : Bool __crystal_pseudo_!, __crystal_pseudo_as(type : Class) __crystal_pseudo_as, __crystal_pseudo_as?(type : Class) __crystal_pseudo_as?, __crystal_pseudo_is_a?(type : Class) : Bool __crystal_pseudo_is_a?, __crystal_pseudo_nil? : Bool __crystal_pseudo_nil?, __crystal_pseudo_responds_to?(name : Symbol) : Bool __crystal_pseudo_responds_to?, class class, dup dup, hash(hasher)
hash hash, inspect : String
inspect(io : IO) : Nil inspect, itself itself, not_nil! not_nil!, pretty_inspect(width = 79, newline = "\n", indent = 0) : String pretty_inspect, pretty_print(pp : PrettyPrint) : Nil pretty_print, tap(&) tap, to_json(io : IO)
to_json to_json, to_pretty_json(indent : String = " ")
to_pretty_json(io : IO, indent : String = " ") to_pretty_json, to_s : String
to_s(io : IO) : Nil to_s, to_yaml(io : IO)
to_yaml to_yaml, try(&) try, unsafe_as(type : T.class) forall T unsafe_as

### Class methods inherited from class `Object`

from_json(string_or_io, root : String)
from_json(string_or_io) from_json, from_yaml(string_or_io : String | IO) from_yaml

##
Constructor Detail

def self.new(default_value : V, initial_capacity = nil) #

Creates a new empty `Hash` where the default_value is returned if a key is missing.

    inventory = Hash(String, Int32).new(0)
    inventory["socks"] = 3
    inventory["pickles"] # => 0

NOTE The default value is passed by reference:

    arr = [1, 2, 3]
    hash = Hash(String, Array(Int32)).new(arr)
    hash["3"][1] = 4
    arr # => [1, 4, 3]

The initial_capacity is useful to avoid unnecessary reallocations of the internal buffer in case of growth. If the number of elements a hash will hold is known, the hash should be initialized with that capacity for improved performance. Otherwise, the default is 11 and inputs less than 11 are ignored.

def self.new(ctx : YAML::ParseContext, node : YAML::Nodes::Node) #
def self.new(pull : JSON::PullParser) #

Reads a Hash from the given pull parser.

Keys are read by invoking `from_json_object_key?` on this hash's key type (`K`), which must return a value of type `K` or `nil`. If `nil` is returned a `JSON::ParseException` is raised.

Values are parsed using the regular `.new(pull : JSON::PullParser)` method.

def self.new #

Creates a new empty `Hash`.

def self.new(block : Hash(K, V), K -> V? = nil, *, initial_capacity = nil) #

Creates a new empty `Hash` with a block for handling missing keys.

    proc = ->(hash : Hash(String, Int32), key : String) { hash[key] = key.size }
    hash = Hash(String, Int32).new(proc)

    hash.size   # => 0
    hash["foo"] # => 3
    hash.size   # => 1
    hash["bar"] = 10
    hash["bar"] # => 10

The initial_capacity is useful to avoid unnecessary reallocations of the internal buffer in case of growth. If the number of elements a hash will hold is known, the hash should be initialized with that capacity for improved performance. Otherwise, the default is 11 and inputs less than 11 are ignored.

def self.new(ctx : YAML::ParseContext, node : YAML::Nodes::Node, &) #
def self.new(initial_capacity = nil, &block : Hash(K, V), K -> V) #

Creates a new empty `Hash` with a block that handles missing keys.

    hash = Hash(String, Int32).new do |hash, key|
      hash[key] = key.size
    end

    hash.size   # => 0
    hash["foo"] # => 3
    hash.size   # => 1
    hash["bar"] = 10
    hash["bar"] # => 10

The initial_capacity is useful to avoid unnecessary reallocations of the internal buffer in case of growth. If the number of elements a hash will hold is known, the hash should be initialized with that capacity for improved performance. Otherwise, the default is 11 and inputs less than 11 are ignored.

##
Class Method Detail

def self.zip(ary1 : Array(K), ary2 : Array(V)) #

Zips two arrays into a `Hash`, taking keys from ary1 and values from ary2.

    Hash.zip(["key1", "key2", "key3"], ["value1", "value2", "value3"])
    # => {"key1" => "value1", "key2" => "value2", "key3" => "value3"}

##
Instance Method Detail

def ==(other : YAML::Any) #
def ==(other : JSON::Any) #
def ==(other : Hash) #

Compares with other. Returns `true` if all key-value pairs are the same.

def [](key) #

Returns the value for the key given by key. If not found, returns the default value given by `Hash.new`, otherwise raises `KeyError`.

    h = {"foo" => "bar"}
    h["foo"] # => "bar"

    h = Hash(String, String).new("bar")
    h["foo"] # => "bar"

    h = Hash(String, String).new { "bar" }
    h["foo"] # => "bar"

    h = Hash(String, String).new
    h["foo"] # raises KeyError

def []=(key : K, value : V) #

Sets the value of key to the given value.

    h = {} of String => String
    h["foo"] = "bar"
    h["foo"] # => "bar"

def []?(key) #

Returns the value for the key given by key. If not found, returns `nil`. This ignores the default value set by `Hash.new`.

    h = {"foo" => "bar"}
    h["foo"]? # => "bar"
    h["bar"]? # => nil

    h = Hash(String, String).new("bar")
    h["foo"]? # => nil

def clear #

Empties a `Hash` and returns it.

    hash = {"foo" => "bar"}
    hash.clear # => {}

def clone #

Similar to `#dup`, but duplicates the values as well.

    hash_a = {"foobar" => {"foo" => "bar"}}
    hash_b = hash_a.clone
    hash_b["foobar"]["foo"] = "baz"
    hash_a # => {"foobar" => {"foo" => "bar"}}

def compact #

Returns new `Hash` without `nil` values.

    hash = {"hello" => "world", "foo" => nil}
    hash.compact # => {"hello" => "world"}

def compact! #

Removes all `nil` value from `self`. Returns `nil` if no changes were made.

    hash = {"hello" => "world", "foo" => nil}
    hash.compact! # => {"hello" => "world"}
    hash.compact! # => nil

def compare_by_identity #

Makes this hash compare keys using their object identity (`object_id)` for types that define such method (`Reference` types, but also structs that might wrap other `Reference` types and delegate the `object_id` method to them).

    h1 = {"foo" => 1, "bar" => 2}
    h1["fo" + "o"]? # => 1

    h1.compare_by_identity
    h1.compare_by_identity? # => true
    h1["fo" + "o"]?         # => nil # not the same String instance

def compare_by_identity? #

Returns `true` of this Hash is comparing keys by `object_id`.

See `#compare_by_identity`.

def delete(key, &) #

Deletes the key-value pair and returns the value, else yields key with given block.

    h = {"foo" => "bar"}
    h.delete("foo") { |key| "#{key} not found" } # => "bar"
    h.fetch("foo", nil)                          # => nil
    h.delete("baz") { |key| "#{key} not found" } # => "baz not found"

def delete(key) #

Deletes the key-value pair and returns the value, otherwise returns `nil`.

    h = {"foo" => "bar"}
    h.delete("foo")     # => "bar"
    h.fetch("foo", nil) # => nil

def delete_if(&) #

Deletes each key-value pair for which the given block returns `true`.

    h = {"foo" => "bar", "fob" => "baz", "bar" => "qux"}
    h.delete_if { |key, value| key.starts_with?("fo") }
    h # => { "bar" => "qux" }

def dig(key : K, *subkeys) #

Traverses the depth of a structure and returns the value, otherwise raises `KeyError`.

    h = {"a" => {"b" => [10, 20, 30]}}
    h.dig "a", "b"                # => [10, 20, 30]
    h.dig "a", "b", "c", "d", "e" # raises KeyError

def dig?(key : K, *subkeys) #

Traverses the depth of a structure and returns the value. Returns `nil` if not found.

    h = {"a" => {"b" => [10, 20, 30]}}
    h.dig? "a", "b"                # => [10, 20, 30]
    h.dig? "a", "b", "c", "d", "e" # => nil

def dup #

Duplicates a `Hash`.

    hash_a = {"foo" => "bar"}
    hash_b = hash_a.dup
    hash_b.merge!({"baz" => "qux"})
    hash_a # => {"foo" => "bar"}

def each #

Returns an iterator over the hash entries. Which behaves like an `Iterator` returning a `Tuple` consisting of the key and value types.

    hsh = {"foo" => "bar", "baz" => "qux"}
    iterator = hsh.each

    iterator.next # => {"foo", "bar"}
    iterator.next # => {"baz", "qux"}

The enumeration follows the order the keys were inserted.

def each(&) : Nil #

Calls the given block for each key-value pair and passes in the key and the value.

    h = {"foo" => "bar"}

    h.each do |key, value|
      key   # => "foo"
      value # => "bar"
    end

    h.each do |key_and_value|
      key_and_value # => {"foo", "bar"}
    end

The enumeration follows the order the keys were inserted.

def each_key(&) #

Calls the given block for each key-value pair and passes in the key.

    h = {"foo" => "bar"}
    h.each_key do |key|
      key # => "foo"
    end

The enumeration follows the order the keys were inserted.

def each_key #

Returns an iterator over the hash keys. Which behaves like an `Iterator` consisting of the key's types.

    hsh = {"foo" => "bar", "baz" => "qux"}
    iterator = hsh.each_key

    key = iterator.next
    key # => "foo"

    key = iterator.next
    key # => "baz"

The enumeration follows the order the keys were inserted.

def each_value(&) #

Calls the given block for each key-value pair and passes in the value.

    h = {"foo" => "bar"}
    h.each_value do |value|
      value # => "bar"
    end

The enumeration follows the order the keys were inserted.

def each_value #

Returns an iterator over the hash values. Which behaves like an `Iterator` consisting of the value's types.

    hsh = {"foo" => "bar", "baz" => "qux"}
    iterator = hsh.each_value

    value = iterator.next
    value # => "bar"

    value = iterator.next
    value # => "qux"

The enumeration follows the order the keys were inserted.

def empty? #

Returns `true` when hash contains no key-value pairs.

    h = Hash(String, String).new
    h.empty? # => true

    h = {"foo" => "bar"}
    h.empty? # => false

def fetch(key, default) #

Returns the value for the key given by key, or when not found the value given by default. This ignores the default value set by `Hash.new`.

    h = {"foo" => "bar"}
    h.fetch("foo", "foo") # => "bar"
    h.fetch("bar", "foo") # => "foo"

def fetch(key, &) #

Returns the value for the key given by key, or when not found calls the given block with the key.

    h = {"foo" => "bar"}
    h.fetch("foo") { "default value" }  # => "bar"
    h.fetch("bar") { "default value" }  # => "default value"
    h.fetch("bar") { |key| key.upcase } # => "BAR"

def first_key #

Returns the first key in the hash.

def first_key? #

Returns the first key if it exists, or returns `nil`.

    hash = {"foo1" => "bar1", "foz2" => "baz2"}
    hash.first_key? # => "foo1"
    hash.clear
    hash.first_key? # => nil

def first_value #

Returns the first value in the hash.

def first_value? #

Returns the first value if it exists, or returns `nil`.

    hash = {"foo1" => "bar1", "foz2" => "baz2"}
    hash.first_value? # => "bar1"
    hash.clear
    hash.first_value? # => nil

def has_key?(key) #

Returns `true` when key given by key exists, otherwise `false`.

    h = {"foo" => "bar"}
    h.has_key?("foo") # => true
    h.has_key?("bar") # => false

def has_value?(val) #

Returns `true` when value given by value exists, otherwise `false`.

    h = {"foo" => "bar"}
    h.has_value?("foo") # => false
    h.has_value?("bar") # => true

def hash(hasher) #

See `Object#hash(hasher)`

def inspect(io : IO) : Nil #
Description copied from class Reference

Appends a String representation of this object which includes its class name, its object address and the values of all instance variables.

    class Person
      def initialize(@name : String, @age : Int32)
      end
    end

    Person.new("John", 32).inspect # => #<Person:0x10fd31f20 @name="John", @age=32>

def invert #

Inverts keys and values. If there are duplicated values, the last key becomes the new value.

    {"foo" => "bar"}.invert                 # => {"bar" => "foo"}
    {"foo" => "bar", "baz" => "bar"}.invert # => {"bar" => "baz"}

def key_for(value) #

Returns a key with the given value, else raises `KeyError`.

    hash = {"foo" => "bar", "baz" => "qux"}
    hash.key_for("bar")    # => "foo"
    hash.key_for("qux")    # => "baz"
    hash.key_for("foobar") # raises KeyError (Missing hash key for value: foobar)

def key_for(value, &) #

Returns a key with the given value, else yields value with the given block.

    hash = {"foo" => "bar"}
    hash.key_for("bar") { |value| value.upcase } # => "foo"
    hash.key_for("qux") { |value| value.upcase } # => "QUX"

def key_for?(value) #

Returns a key with the given value, else `nil`.

    hash = {"foo" => "bar", "baz" => "qux"}
    hash.key_for?("bar")    # => "foo"
    hash.key_for?("qux")    # => "baz"
    hash.key_for?("foobar") # => nil

def key_index(key) #

Returns the index of the given key, or `nil` when not found. The keys are ordered based on when they were inserted.

    h = {"foo" => "bar", "baz" => "qux"}
    h.key_index("foo") # => 0
    h.key_index("qux") # => nil

def keys : Array(K) #

Returns a new `Array` with all the keys.

    h = {"foo" => "bar", "baz" => "bar"}
    h.keys # => ["foo", "baz"]

def last_key #

Returns the last key in the hash.

def last_key? #

Returns the last key if it exists, or returns `nil`.

    hash = {"foo1" => "bar1", "foz2" => "baz2"}
    hash.last_key? # => "foz2"
    hash.clear
    hash.last_key? # => nil

def last_value #

Returns the last value in the hash.

def last_value? #

Returns the last value if it exists, or returns `nil`.

    hash = {"foo1" => "bar1", "foz2" => "baz2"}
    hash.last_value? # => "baz2"
    hash.clear
    hash.last_value? # => nil

def merge(other : Hash(L, W), &block : K, V, W -> V | W) forall L, W #
def merge(other : Hash(L, W)) forall L, W #

Returns a new `Hash` with the keys and values of this hash and other combined. A value in other takes precedence over the one in this hash.

    hash = {"foo" => "bar"}
    hash.merge({"baz" => "qux"})
    # => {"foo" => "bar", "baz" => "qux"}
    hash
    # => {"foo" => "bar"}

def merge!(other : Hash) #

Similar to `#merge`, but the receiver is modified.

    hash = {"foo" => "bar"}
    hash.merge!({"baz" => "qux"})
    hash # => {"foo" => "bar", "baz" => "qux"}

def merge!(other : Hash, &) : self #

Adds the contents of other to this hash. If a key exists in both hashes, the given block is called to determine the value to be used. The block arguments are the key, the value in `self` and the value in other.

    hash = {"a" => 100, "b" => 200}
    other = {"b" => 254, "c" => 300}
    hash.merge!(other) { |key, v1, v2| v1 + v2 }
    hash # => {"a" => 100, "b" => 454, "c" => 300}

def pretty_print(pp) : Nil #
def put(key : K, value : V, &) #

Sets the value of key to the given value.

If a value already exists for `key`, that (old) value is returned. Otherwise the given block is invoked with key and its value is returned.

    h = {} of Int32 => String
    h.put(1, "one") { "didn't exist" } # => "didn't exist"
    h.put(1, "uno") { "didn't exist" } # => "one"
    h.put(2, "two") { |key| key.to_s } # => "2"

def rehash : Nil #

Rebuilds the hash table based on the current value of each key.

When using mutable data types as keys, changing the value of a key after it was inserted into the `Hash` may lead to undefined behaviour. This method re-indexes the hash using the current key values.

def reject(*keys) #

Returns a new `Hash` without the given keys.

    {"a" => 1, "b" => 2, "c" => 3, "d" => 4}.reject("a", "c") # => {"b" => 2, "d" => 4}

def reject(&block : K, V -> _) #

Returns a new hash consisting of entries for which the block returns `false`.

    h = {"a" => 100, "b" => 200, "c" => 300}
    h.reject { |k, v| k > "a" } # => {"a" => 100}
    h.reject { |k, v| v < 200 } # => {"b" => 200, "c" => 300}

def reject!(*keys) #
def reject!(keys : Array | Tuple) #

Removes a list of keys out of hash.

    h = {"a" => 1, "b" => 2, "c" => 3, "d" => 4}.reject!("a", "c")
    h # => {"b" => 2, "d" => 4}

def reject!(&block : K, V -> _) #

Equivalent to `Hash#reject`, but makes modification on the current object rather that returning a new one. Returns `nil` if no changes were made.

def select(&block : K, V -> _) #

Returns a new hash consisting of entries for which the block returns `true`.

    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}

def select(keys : Array | Tuple) #

Returns a new `Hash` with the given keys.

    {"a" => 1, "b" => 2, "c" => 3, "d" => 4}.select({"a", "c"}) # => {"a" => 1, "c" => 3}
    {"a" => 1, "b" => 2, "c" => 3, "d" => 4}.select("a", "c")   # => {"a" => 1, "c" => 3}
    {"a" => 1, "b" => 2, "c" => 3, "d" => 4}.select(["a", "c"]) # => {"a" => 1, "c" => 3}

def select(*keys) #

Returns a new `Hash` with the given keys.

    {"a" => 1, "b" => 2, "c" => 3, "d" => 4}.select({"a", "c"}) # => {"a" => 1, "c" => 3}
    {"a" => 1, "b" => 2, "c" => 3, "d" => 4}.select("a", "c")   # => {"a" => 1, "c" => 3}
    {"a" => 1, "b" => 2, "c" => 3, "d" => 4}.select(["a", "c"]) # => {"a" => 1, "c" => 3}

def select!(&block : K, V -> _) #

Equivalent to `Hash#select` but makes modification on the current object rather that returning a new one. Returns `nil` if no changes were made

def select!(*keys) #

Removes every element except the given ones.

    h1 = {"a" => 1, "b" => 2, "c" => 3, "d" => 4}.select!({"a", "c"})
    h2 = {"a" => 1, "b" => 2, "c" => 3, "d" => 4}.select!("a", "c")
    h3 = {"a" => 1, "b" => 2, "c" => 3, "d" => 4}.select!(["a", "c"])
    h1 == h2 == h3 # => true
    h1             # => {"a" => 1, "c" => 3}

def select!(keys : Array | Tuple) #

Removes every element except the given ones.

    h1 = {"a" => 1, "b" => 2, "c" => 3, "d" => 4}.select!({"a", "c"})
    h2 = {"a" => 1, "b" => 2, "c" => 3, "d" => 4}.select!("a", "c")
    h3 = {"a" => 1, "b" => 2, "c" => 3, "d" => 4}.select!(["a", "c"])
    h1 == h2 == h3 # => true
    h1             # => {"a" => 1, "c" => 3}

def shift #

Deletes and returns the first key-value pair in the hash, or raises `IndexError` if the hash is empty.

    hash = {"foo" => "bar", "baz" => "qux"}
    hash.shift # => {"foo", "bar"}
    hash       # => {"baz" => "qux"}

    hash = {} of String => String
    hash.shift # raises IndexError

def shift(&) #

Deletes and returns the first key-value pair in the hash. Yields to the given block if the hash is empty.

    hash = {"foo" => "bar", "baz" => "qux"}
    hash.shift { true } # => {"foo", "bar"}
    hash                # => {"baz" => "qux"}

    hash = {} of String => String
    hash.shift { true } # => true
    hash                # => {}

def shift? #

Same as `#shift`, but returns `nil` if the hash is empty.

    hash = {"foo" => "bar", "baz" => "qux"}
    hash.shift? # => {"foo", "bar"}
    hash        # => {"baz" => "qux"}

    hash = {} of String => String
    hash.shift? # => nil

def size : Int32 #

Returns the number of elements in this Hash.

def to_a : Array(Tuple(K, V)) #

Returns an array of tuples with key and values belonging to this Hash.

    h = {1 => 'a', 2 => 'b', 3 => 'c'}
    h.to_a # => [{1, 'a'}, {2, 'b'}, {3, 'c'}]

def to_h #

Returns `self`.

def to_json(json : JSON::Builder) #

Serializes this Hash into JSON.

Keys are serialized by invoking `to_json_object_key` on them. Values are serialized with the usual `#to_json(json : JSON::Builder)` method.

def to_s(io : IO) : Nil #

Converts to a `String`.

    h = {"foo" => "bar"}
    h.to_s       # => "{\"foo\" => \"bar\"}"
    h.to_s.class # => String

def to_yaml(yaml : YAML::Nodes::Builder) #
def transform_keys(&block : K -> K2) forall K2 #

Returns a new hash with all keys converted using the block operation. The block can change a type of keys.

    hash = {:a => 1, :b => 2, :c => 3}
    hash.transform_keys { |key| key.to_s } # => {"a" => 1, "b" => 2, "c" => 3}

def transform_values(&block : V -> V2) forall V2 #

Returns a new hash with the results of running block once for every value. The block can change a type of values.

    hash = {:a => 1, :b => 2, :c => 3}
    hash.transform_values { |value| value + 1 } # => {:a => 2, :b => 3, :c => 4}

def transform_values!(&block : V -> V) #

Destructively transforms all values using a block. Same as transform_values but modifies in place. The block cannot change a type of values.

    hash = {:a => 1, :b => 2, :c => 3}
    hash.transform_values! { |value| value + 1 }
    hash # => {:a => 2, :b => 3, :c => 4}

def values : Array(V) #

Returns only the values as an `Array`.

    h = {"foo" => "bar", "baz" => "qux"}
    h.values # => ["bar", "qux"]

def values_at(*indexes : K) #

Returns a tuple populated with the elements at the given indexes. Raises if any index is invalid.

    {"a" => 1, "b" => 2, "c" => 3, "d" => 4}.values_at("a", "c") # => {1, 3}