lis*_*tor 10 mapping list perl6 sequential raku
法线贴图将函数应用于列表元素,并生成结果列表的元素.例如,如果列表是(1, 2, 3,)并映射了square函数,则会得到一个新列表(1, 4, 9,).
有没有办法映射列表的一组顺序元素?例如,如果列表是<8 2 7 2 6 9 4 9 6 1>,我想计算列表中每2个元素的总和<10 9 9 8 15 13 13 15 7>?
我当然可以写一个例程来遍历列表.但我正在寻找一种更简单的方法,如减少运算符或像聚集/采取.
sml*_*mls 11
您可以使用该.rotor方法将列表分区为重叠的子列表:
say <8 2 7 2 6 9 4 9 6 1>.rotor(2 => -1);
# Output:
# ((8 2) (2 7) (7 2) (2 6) (6 9) (9 4) (4 9) (9 6) (6 1))
Run Code Online (Sandbox Code Playgroud)
这2 => -1是一个Pair参数,它表示该方法应该通过在每一步中"前进两个,后退一个"来生成子列表.
然后,您只需使用.map将您的操作(例如总和)应用于每个子列表:
say <8 2 7 2 6 9 4 9 6 1>.rotor(2 => -1).map(*.sum);
# Output:
# (10 9 9 8 15 13 13 15 7)
Run Code Online (Sandbox Code Playgroud)
执行此操作的函数式编程方法是两次引用列表,通过元素偏移一个版本,并将它们压缩在一起.这为您提供了后续元素的所有元组.
my @l := <a b c d e f>;
say @l Z @l[1..*]; # output: ((a b) (b c) (c d) (d e) (e f))
Run Code Online (Sandbox Code Playgroud)
如果您不想创建临时变量来保存列表,请使用given(do given如果需要语句返回值,则使用):
given <8 2 7 2 6 9 4 9 6 1> {
say ($_ Z $_[1..*]).map: -> [$a, $b] { $a+$b };
}
Run Code Online (Sandbox Code Playgroud)
如果您正在使用一个带有两个参数的函数,您可能希望在压缩后展平列表,并一次map取两个元素:
given <8 2 7 2 6 9 4 9 6 1> {
say ($_ Z $_[1..*]).flat.map(&infix:<+>);
}
Run Code Online (Sandbox Code Playgroud)