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.
First sort the keys by the associated value. Then get the values (e.g. by using a hash slice). my @keys = sort { $h{$a} <=> $h{$b} } keys(%h); my @vals = @h{@keys}; Or if you have a hash reference.
Hashtable is a data structure that stores data in key-value format. The stored data is neither in sorted order nor preserves the insertion order.
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.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With