【发布时间】:2017-12-07 04:27:31
【问题描述】:
假设我有一个描述货币数量的嵌套哈希:
my %money = (coins => {'50c' => 4}, notes => {'10' => 1, '20' => 5});
我想要的格式是记录列表:
my @money = [
(:type('coins'), :subtype('50c'), value => 4),
(:type('notes'), :subtype('10'), value => 1),
(:type('notes'), :subtype('20'), value => 5),
];
最明显的答案是循环:
my @money;
for %money.kv -> $type, %sub-records {
for %sub-records.kv -> $subtype, $value {
@money.push: (:$type, :$subtype, :$value);
}
}
但我对将变量从填充它的代码中分离出来很敏感。接下来,我尝试在输入哈希上创建具有函数转换的变量:
%money.kv.map: -> $k1, %hsh2 { :type($k1) X, %hsh2.kv.map(->$k2, $v2 {:subtype($k2), :$v2, :value($v2)}) }
但我没有正确嵌套。我想要一个平面列表的列表。另外,上面的内容是一团糟。
折衷方案是 gather/take 构造,它允许我通过迭代构造一个列表,而在主范围内没有任何临时/未初始化的垃圾:
my @money = gather for %money.kv -> $type, %sub-records {
for %sub-records.kv -> $subtype, $value {
take (:$type, :$subtype, :$value);
}
};
但我很好奇,仅通过 map、X 或 Z 和 flat 等列表转换来实现此目的的正确方法是什么? (“key1”、“key2”和“value”是很好的字段名称,因为算法不应该是特定于域的。)
编辑:我应该提一下,在 Perl 6 中,gather/take 是最易读的解决方案(最适合非只写代码)。我仍然对纯函数解决方案感到好奇。
【问题讨论】:
-
我觉得
gather/take这个用法很好 -
@BradGilbert 我也这样做,因为它可能是最易读的解决方案,但我对纯函数方式很好奇。我现在正在阅读您的回答。
标签: functional-programming raku