struct NamedTuple(**T)
inherits Value
¶
A named tuple is a fixed-size, immutable, stack-allocated mapping of a fixed set of keys to values.
You can think of a NamedTuple
as an immutable Hash
whose keys (which
are of type Symbol
), and the types for each key, are known at compile time.
A named tuple can be created with a named tuple literal:
language = {name: "Crystal", year: 2011} # NamedTuple(name: String, year: Int32)
language[:name] # => "Crystal"
language[:year] # => 2011
language[:other] # compile time error
The compiler knows what types are in each key, so when indexing a named tuple with a symbol literal the compiler will return the value for that key and with the expected type, like in the above snippet. Indexing with a symbol literal for which there's no key will give a compile-time error.
Indexing with a symbol that is only known at runtime will return
a value whose type is the union of all the types in the named tuple,
and might raise KeyError
.
Class methods¶
.types
¶
Returns the types of this named tuple type.
tuple = {a: 1, b: "hello", c: 'x'}
tuple.class.types # => {a: Int32, b: String, c: Char}
.from(hash : Hash) : self
¶
(hash : Hash) : self
Creates a named tuple from the given hash, with elements casted to the given types. Here the Int32 | String union is cast to Int32.
num_or_str = 42.as(Int32 | String)
NamedTuple(name: String, val: Int32).from({"name" => "number", "val" => num_or_str}) # => {name: "number", val: 42}
num_or_str = "a string".as(Int32 | String)
NamedTuple(name: String, val: Int32).from({"name" => "number", "val" => num_or_str}) # raises TypeCastError (cast from String to Int32 failed)
#from
.
.new(**options : **T)
¶
(**options : **T)
Creates a named tuple that will contain the given arguments.
With a named tuple literal you cannot create an empty named tuple. This method doesn't have this limitation, which makes it especially useful in macros and generic code.
NamedTuple.new(name: "Crystal", year: 2011) #=> {name: "Crystal", year: 2011}
NamedTuple.new # => {}
{} # syntax error
Methods¶
#==(other : NamedTuple)
¶
(other : NamedTuple)
Returns true
if this tuple has the same keys as other, and values
for each key are the same in self
and other.
tuple1 = {name: "Crystal", year: 2011}
tuple2 = {year: 2011, name: "Crystal"}
tuple3 = {name: "Crystal", year: 2012}
tuple4 = {name: "Crystal", year: 2011.0}
tuple1 == tuple2 # => true
tuple1 == tuple3 # => false
tuple1 == tuple4 # => true
#==(other : self)
¶
(other : self)
Returns true
if this tuple has the same keys as other, and values
for each key are the same in self
and other.
tuple1 = {name: "Crystal", year: 2011}
tuple2 = {year: 2011, name: "Crystal"}
tuple3 = {name: "Crystal", year: 2012}
tuple4 = {name: "Crystal", year: 2011.0}
tuple1 == tuple2 # => true
tuple1 == tuple3 # => false
tuple1 == tuple4 # => true
#[](key : Symbol | String)
¶
(key : Symbol | String)
Returns the value for the given key, if there's such key, otherwise raises KeyError
.
tuple = {name: "Crystal", year: 2011}
key = :name
tuple[key] # => "Crystal"
key = "year"
tuple[key] # => 2011
key = :other
tuple[key] # raises KeyError
#[]?(key : Symbol | String)
¶
(key : Symbol | String)
Returns the value for the given key, if there's such key, otherwise returns nil
.
tuple = {name: "Crystal", year: 2011}
key = :name
tuple[key]? # => "Crystal"
key = "year"
tuple[key] # => 2011
key = :other
tuple[key]? # => nil
#clone
¶
Returns a named tuple with the same keys but with cloned values, using the clone
method.
#dig(key : Symbol | String, *subkeys)
¶
(key : Symbol | String, *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
#dig?(key : Symbol | String, *subkeys)
¶
(key : Symbol | String, *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
#each(&) : Nil
¶
(&) : Nil
Yields each key and value in this named tuple.
tuple = {name: "Crystal", year: 2011}
tuple.each do |key, value|
puts "#{key} = #{value}"
end
Output:
name = Crystal
year = 2011
#each_key(&) : Nil
¶
(&) : Nil
Yields each key in this named tuple.
tuple = {name: "Crystal", year: 2011}
tuple.each_key do |key|
puts key
end
Output:
name
year
#each_value(&) : Nil
¶
(&) : Nil
Yields each value in this named tuple.
tuple = {name: "Crystal", year: 2011}
tuple.each_value do |value|
puts value
end
Output:
Crystal
2011
#each_with_index(offset = 0
¶
(offset = 0
Yields each key and value, together with an index starting at offset, in this named tuple.
tuple = {name: "Crystal", year: 2011}
tuple.each_with_index do |key, value, i|
puts "#{i + 1}) #{key} = #{value}"
end
Output:
1) name = Crystal
2) year = 2011
#empty?
¶
Returns true
if this named tuple is empty.
tuple = {name: "Crystal", year: 2011}
tuple.empty? # => false
#fetch(key : Symbol | String, default_value)
¶
(key : Symbol | String, default_value)
Returns the value for the given key, if there's such key, otherwise returns default_value.
tuple = {name: "Crystal", year: 2011}
tuple.fetch(:name, "Unknown") # => "Crystal"
tuple.fetch("year", 0) # => 2011
tuple.fetch(:other, 0) # => 0
#fetch(key : Symbol
¶
(key : Symbol
Returns the value for the given key, if there's such key, otherwise the value returned by the block.
tuple = {name: "Crystal", year: 2011}
tuple.fetch(:name) { "Unknown" } # => "Crystal"
tuple.fetch(:other) { 0 } # => 0
#fetch(key : String
¶
(key : String
Returns the value for the given key, if there's such key, otherwise the value returned by the block.
tuple = {name: "Crystal", year: 2011}
tuple.fetch("name") { "Unknown" } # => "Crystal"
tuple.fetch("other") { 0 } # => 0
#from(hash : Hash)
¶
(hash : Hash)
Expects to be called on a named tuple whose values are types, creates a tuple from the given hash, with types casted appropriately. The hash keys must be either symbols or strings.
This allows you to easily pass a hash as individual named arguments to a method.
require "json"
def speak_about(thing : String, n : Int64)
"I see #{n} #{thing}s"
end
hash = JSON.parse(%({"thing": "world", "n": 2})).as_h # hash : Hash(String, JSON::Any)
hash = hash.transform_values(&.raw) # hash : Hash(String, JSON::Any::Type)
speak_about(**{thing: String, n: Int64}.from(hash)) # => "I see 2 worlds"
#has_key?(key : String) : Bool
¶
(key : String) : Bool
Returns true
if this named tuple has the given key, false
otherwise.
tuple = {name: "Crystal", year: 2011}
tuple.has_key?(:name) # => true
tuple.has_key?(:other) # => false
#has_key?(key : Symbol) : Bool
¶
(key : Symbol) : Bool
Returns true
if this named tuple has the given key, false
otherwise.
tuple = {name: "Crystal", year: 2011}
tuple.has_key?(:name) # => true
tuple.has_key?(:other) # => false
#hash(hasher)
¶
(hasher)
Returns a hash value based on this name tuple's size, keys and values.
See also: Object#hash
.
See Object#hash(hasher)
#keys
¶
Returns a Tuple
of symbols with the keys in this named tuple.
tuple = {name: "Crystal", year: 2011}
tuple.keys # => {:name, :year}
#map
¶
Returns an Array
populated with the results of each iteration in the given block,
which is given each key and value in this named tuple.
tuple = {name: "Crystal", year: 2011}
tuple.map { |k, v| "#{k}: #{v}" } # => ["name: Crystal", "year: 2011"]
#merge(other : NamedTuple)
¶
(other : NamedTuple)
Merges two named tuples into one, returning a new named tuple. If a key is defined in both tuples, the value and its type is used from other.
a = {foo: "Hello", bar: "Old"}
b = {bar: "New", baz: "Bye"}
a.merge(b) # => {foo: "Hello", bar: "New", baz: "Bye"}
#merge(**other : **U) forall U
¶
(**other : **U) forall U
Merges two named tuples into one, returning a new named tuple. If a key is defined in both tuples, the value and its type is used from other.
a = {foo: "Hello", bar: "Old"}
b = {bar: "New", baz: "Bye"}
a.merge(b) # => {foo: "Hello", bar: "New", baz: "Bye"}
#size
¶
Returns the number of elements in this named tuple.
tuple = {name: "Crystal", year: 2011}
tuple.size # => 2
#sorted_keys
¶
Returns a Tuple
of symbols with the keys in this named tuple, sorted by name.
tuple = {foo: 1, bar: 2, baz: 3}
tuple.sorted_keys # => {:bar, :baz, :foo}
#to_a
¶
Returns a new Array
of tuples populated with each key-value pair.
tuple = {name: "Crystal", year: 2011}
tuple.to_a # => [{:name, "Crystal"}, {:year, 2011}]
#to_h
¶
Returns a Hash
with the keys and values in this named tuple.
tuple = {name: "Crystal", year: 2011}
tuple.to_h # => {:name => "Crystal", :year => 2011}
#to_s(io : IO) : Nil
¶
(io : IO) : Nil
Appends a string representation of this named tuple to the given IO
.
tuple = {name: "Crystal", year: 2011}
tuple.to_s # => %({name: "Crystal", year: 2011})
#values
¶
Returns a Tuple
with the values in this named tuple.
tuple = {name: "Crystal", year: 2011}
tuple.values # => {"Crystal", 2011}