Immutable mapping from strings to values
does Associative does Iterable
A Map
is an immutable mapping from string keys to values of arbitrary types. It serves as a base class for Hash, which is mutable.
In list context a Map
behaves as a list of Pair objects.
Note that the order in which keys, values and pairs are retrieved is generally arbitrary, but the keys
, values
and pairs
methods return them always in the same order when called on the same object.
my := Map.new('a', 1, 'b', 2);say .keys; # can print «a b» or «b a»say .values; # prints «1 2» if the previous line# printed «a b», «2 1» otherwise
To retrieve a value from the Map by key, use the { }
postcircumfix operator:
my is Map = 'a', 1, 'b', 2;say ; # OUTPUT: «1»say ; # OUTPUT: «(1 2)»
To check whether a given key is stored in a Map, modify the access with the :exists
adverb:
my = Map.new('a', 1, 'b', 2);my = 'a';if :exists
Being an immutable instance, it is not possible to add keys after a Map
has been initialized:
my = Map.new( 'a', 1, 'b', 2 );= 'foo'; # WRONG!# Cannot modify an immutable Str
Unlike its mutable companion type Hash, a Map cannot be parameterized by key or value types.
method new(*)
Creates a new Map from a list of alternating keys and values, with the same semantics as described in the Hashes and maps documentation, but also accepts Pair
s instead of separate keys and values. Use the grouping operator or quote the key to ensure that a literal pair is not interpreted as a named argument.
my = Map.new('a', 1, 'b', 2);# WRONG: :b(2) interpreted as named argumentsay Map.new('a', 1, :b(2)).keys; # OUTPUT: «(a)»# RIGHT: :b(2) interpreted as Pair because of extra parenthesessay Map.new( ('a', 1, :b(2)) ).keys.sort; # OUTPUT: «(a b)»# RIGHT: 'b' => 2 always creates a Pairsay Map.new('a', 1, 'b' => 2).keys.sort; # OUTPUT: «(a b)»
A shorthand syntax for creating Maps is provided:
my is Map = 'a', 1, 'b', 2;
method elems(Map: --> Int)
Returns the number of pairs stored in the Map.
my = Map.new('a', 1, 'b', 2);say .elems; # OUTPUT: «2»
multi method ACCEPTS(Map: Positional )multi method ACCEPTS(Map: Cool )multi method ACCEPTS(Map: Regex )multi method ACCEPTS(Map: Any )
Used in smartmatching if the right-hand side is an Map
.
If the topic is list-like (Positional), returns True if any of the list elements exist as a key in the Map.
If the topic is of type Cool
(strings, integers etc.), returns True if the topic exists as a key.
If the topic is a regex, returns True if any of the keys match the regex.
As a fallback, the topic is coerced to a list, and the Positional
behavior is applied.
method gist(Map: --> Str)
Returns the string containing the "gist" of the Map, sorts the pairs and lists up to the first 100, appending an ellipsis if the Map has more than 100 pairs.
method keys(Map: --> Seq)
Returns a Seq
of all keys in the Map.
my = Map.new('a' => (2, 3), 'b' => 17);say .keys; # OUTPUT: «(a b)»
method values(Map: --> Seq)
Returns a Seq
of all values in the Map.
my = Map.new('a' => (2, 3), 'b' => 17);say .values; # OUTPUT: «((2 3) 17)»
method pairs(Map: --> Seq)
Returns a Seq
of all pairs in the Map.
my = Map.new('a' => (2, 3), 'b' => 17);say .pairs; # OUTPUT: «(a => (2 3) b => 17)»
method antipairs(Map: --> Seq)
Returns all keys and their respective values as a Seq of Pair
s where the keys and values have been exchanged, i.e. the opposite of method pairs. Unlike the invert
method, there is no attempt to expand list values into multiple pairs.
my = Map.new('a' => (2, 3), 'b' => 17);say .antipairs; # OUTPUT: «((2 3) => a 17 => b)»
method invert(Map: --> Seq)
Returns all keys and their respective values as a Seq of Pair
s where the keys and values have been exchanged. The difference between invert
and antipairs
is that invert
expands list values into multiple pairs.
my = Map.new('a' => (2, 3), 'b' => 17);say .invert; # OUTPUT: «(2 => a 3 => a 17 => b)»
method kv(Map: --> Seq)
Returns a Seq
of keys and values interleaved.
Map.new('a', 1, 'b', 2).kv # (a 1 b 2)
multi method list(Map: --> List)
Returns a List
of Pair objects of all keys and values in the Map.
my = Map.new('a' => (2, 3), 'b' => 17);say .list; # OUTPUT: «(b => 17 a => (2 3))»
multi method sort(Map: --> Seq)
Returns a Seq of Pair objects, which are the pairs of the hash, sorted by key. Equivalent to %hash.sort: *.key
# These are equivalent:say Map.new(<c 3 a 1 b 2>).sort; # OUTPUT: «(a => 1 b => 2 c => 3)»say Map.new(<c 3 a 1 b 2>).sort: *.key; # OUTPUT: «(a => 1 b => 2 c => 3)»
See Any.sort for additional available candidates.
method Int(Map: --> Int)
Returns the number of pairs stored in the Map
(same as .elems
).
my = Map.new('a' => 2, 'b' => 17);say .Int; # OUTPUT: «2»
method Numeric(Map: --> Int)
Returns the number of pairs stored in the Map
(same as .elems
).
my = Map.new('a' => 2, 'b' => 17);say .Numeric; # OUTPUT: «2»
method Bool(Map: --> Bool)
Returns True
if the invocant contains at least one key/value pair.
my = Map.new('a' => 2, 'b' => 17);say .Bool; # OUTPUT: «True»
method Capture(Map:)
Returns a Capture where each key, if any, has been converted to a named argument with the same value as it had in the original Map
. The returned Capture
will not contain any positional arguments.
my = Map.new('a' => 2, 'b' => 17);my = .Capture;my-sub(|); # OUTPUT: «2, 17»sub my-sub(:, :)