W3cubDocs

/Crystal 0.31

class Hash(K, V)

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

Defined in:

hash.cr
json/any.cr
json/to_json.cr
yaml/any.cr
yaml/to_yaml.cr

Constructors

Class Method Summary

Instance Method Summary

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?(&block)
all?(pattern)
all? all?
, any?(&block)
any?(pattern)
any? any?
, chunks(&block : {K, V} -> U) forall U chunks, compact_map(&block) compact_map, count(item)
count(&block) count
, cycle(&block)
cycle(n, &block) cycle
, each(&block : {K, V} -> UNDERSCORE) each, each_cons(count : Int, reuse = false, &block) each_cons, each_slice(count : Int, reuse = false, &block) each_slice, each_with_index(offset = 0, &block) each_with_index, each_with_object(obj, &block) each_with_object, find(if_none = nil, &block) 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, &block) forall U in_groups_of
, includes?(obj) includes?, index(&block)
index(obj) index
, index_by(&block : {K, V} -> U) forall U index_by, join(separator = "", &block)
join(separator, io, &block)
join(separator, io)
join(separator = "") join
, map(&block : {K, V} -> U) forall U map, map_with_index(&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?(&block) none?
, one?(&block)
one?(pattern)
one? one?
, partition(&block) partition, product(&block)
product(initial : Number, &block)
product
product(initial : Number) product
, reduce(memo, &block)
reduce(&block) reduce
, reduce?(&block) 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(&block) skip_while, sum(initial)
sum
sum(initial, &block)
sum(&block) sum
, take_while(&block) 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, &block)
zip(*others : Indexable | Iterable | Iterator) zip
, zip?(*others : Indexable | Iterable | Iterator, &block)
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) =~, class class, dup dup, hash(hasher)
hash hash
, inspect(io : IO) : Nil
inspect : String 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(&block) 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(&block) try, unsafe_as(type : T.class) forall T unsafe_as

Constructor methods inherited from class Object

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

Constructor Detail

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

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)Source

def self.new(pull : JSON::PullParser)Source

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

Creates a new empty Hash.

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

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, &block)Source

def self.new(initial_capacity = nil, &block : Hash(K, V), K -> V)Source

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))Source

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)Source

def ==(other : Hash)Source

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

def ==(other : JSON::Any)Source

def [](key)Source

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)Source

Sets the value of key to the given value.

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

def []?(key)Source

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 clearSource

Empties a Hash and returns it.

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

def cloneSource

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 compactSource

Returns new Hash without nil values.

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

def compact!Source

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 delete(key)Source

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(key, &block)Source

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_if(&block)Source

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)Source

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)Source

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 dupSource

Duplicates a Hash.

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

def each(&block) : NilSource

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 eachSource

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_keySource

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_key(&block)Source

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_valueSource

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 each_value(&block)Source

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 empty?Source

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, &block)Source

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 fetch(key, default)Source

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 first_keySource

Returns the first key in the hash.

def first_key?Source

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_valueSource

Returns the first value in the hash.

def first_value?Source

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)Source

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)Source

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)Source

def inspect(io : IO) : NilSource

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 invertSource

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, &block)Source

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)Source

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)Source

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)Source

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)Source

Returns a new Array with all the keys.

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

def last_keySource

Returns the last key in the hash.

def last_key?Source

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_valueSource

Returns the last value in the hash.

def last_value?Source

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)) forall L, WSource

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(L, W), &block : K, V, W -> V | W) forall L, WSource

def merge!(other : Hash)Source

Similar to #merge, but the receiver is modified.

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

def merge!(other : Hash, &block)Source

def pretty_print(pp) : NilSource

def put(key : K, value : V, &block)Source

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 : NilSource

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)Source

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 -> UNDERSCORE)Source

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)Source

def reject!(keys : Array | Tuple)Source

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 -> UNDERSCORE)Source

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(*keys)Source

def select(keys : Array | Tuple)Source

Returns a new Hash with the given keys.

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

def select(&block : K, V -> UNDERSCORE)Source

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)Source

Removes every element except the given ones.

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

def select!(&block : K, V -> UNDERSCORE)Source

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)Source

def shiftSource

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(&block)Source

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?Source

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 : Int32Source

Returns the number of elements in this Hash.

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

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_hSource

Returns self.

def to_json(json : JSON::Builder)Source

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) : NilSource

Converts to a String.

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

def to_yaml(yaml : YAML::Nodes::Builder)Source

def transform_keys(&block : K -> K2) forall K2Source

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 V2Source

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)Source

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)Source

Returns only the values as an Array.

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

def values_at(*indexes : K)Source

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}

© 2012–2019 Manas Technology Solutions.
Licensed under the Apache License, Version 2.0.
https://crystal-lang.org/api/0.31.1/Hash.html