Reputation: 2125
I have a hash %h
and I want to process the data in a for
statement in alphabetical order of keys.
But if I use a sort
on the hash I get a list of Pair
s, which is understandable. But how do I unpack this for a for
statement.
Currently I'm using the following:
my %h = <xabsu ieunef runf awww bbv> Z=> 1..*; # create a hash with random key names
for %h.sort {
my ($name, $num) = (.key, .value);
say "name: $name, num: $num"
}
# Output
# name: awww, num: 4
# name: bbv, num: 5
# name: ieunef, num: 2
# name: runf, num: 3
# name: xabsu, num: 1
But I would prefer something like the more idiomatic form:
my %h = <xabsu ieunef runf awww bbv> Z=> 1..*; # create a hash with random key names
for %h.sort -> $name, $num {
say "name: $name, num: $num"
}
# Output
# name: awww 4, num: bbv 5
# name: ieunef 2, num: runf 3
# Too few positionals passed; expected 2 arguments but got 1
# in block <unit> at <unknown file> line 1
I'm sure there is a neater way to 'unpack' the Pair into a signature for the for
statement.
Upvotes: 9
Views: 147
Reputation: 2125
Raising @Joshua 's comment to an answer, a neater way is:
%h.sort.map(|*.kv) -> $name,$num { ... }
This uses two Raku features:
*
inside the map is the Whatever star to create a closure|
flattens the resultant list, so that after ->
the $name, $num
variables do not need to be inside parens.Upvotes: 2
Reputation: 26924
The neater way:
for %h.sort -> (:key($name), :value($num)) {
This destructures the Pair
by calling .key
and .value
on it, and then binding them to $name
and $num
respectively.
Perhaps a shorter, more understandable version:
for %h.sort -> (:$key, :$value) {
which would create variables with the same names the methods got called with.
Upvotes: 11