如何在 for 中对哈希使用排序

How do use a sort on a hash in a for

我有一个散列 %h,我想按键的字母顺序处理 for 语句中的数据。

但是如果我在散列上使用 sort,我会得到一个 Pair 的列表,这是可以理解的。但是我如何将其解压为 for 语句。

目前我使用的是:

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

但我更喜欢更惯用的形式:

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

我确定有一种更简洁的方法可以将 'unpack' 配对变成 for 语句的签名。

更简洁的方法:

for %h.sort -> (:key($name), :value($num)) {

这通过调用 .key.value 来解构 Pair,然后分别将它们绑定到 $name$num

也许是更短、更容易理解的版本:

for %h.sort -> (:$key, :$value) {

这将创建与调用方法同名的变量。

将@Joshua 的评论提升到一个答案,更简洁的方法是:

%h.sort.map(|*.kv) -> $name,$num { ... }

这使用了两个 Raku 功能:

  • * 地图里面是 Whatever star 来创建闭包
  • | 将结果列表展平,因此在 -> 之后 $name, $num 变量不需要在括号内。