映射一组顺序列表元素的简单方法
Simple way to do mapping of group of sequential list elements
法线映射将函数应用于列表元素并生成结果列表的元素。例如,如果列表是 (1, 2, 3,)
并映射平方函数,您将得到一个新列表 (1, 4, 9,)
.
有没有办法映射列表的一组顺序元素?例如,如果列表是 <8 2 7 2 6 9 4 9 6 1>
并且我想计算列表中每 2 个元素的总和以使 <10 9 9 8 15 13 13 15 7>
?
我当然可以写一个遍历列表的例程。但我正在寻找一种更简单的方法,例如缩减运算符或 gather/take。
执行此操作的函数式编程方法是引用列表两次,将一个版本偏移一个元素,然后将它们压缩在一起。这为您提供了后续元素的所有元组。
my @l := <a b c d e f>;
say @l Z @l[1..*]; # output: ((a b) (b c) (c d) (d e) (e f))
如果您不想创建一个临时变量来保存列表,请使用 given
(如果您需要 return 一个值的语句,请使用 do given
):
given <8 2 7 2 6 9 4 9 6 1> {
say ($_ Z $_[1..*]).map: -> [$a, $b] { $a+$b };
}
如果您使用的函数带有两个参数,您可能希望在压缩后展平列表并让 map
一次带两个元素:
given <8 2 7 2 6 9 4 9 6 1> {
say ($_ Z $_[1..*]).flat.map(&infix:<+>);
}
您可以使用 .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))
2 => -1
是一个 Pair
参数,它向方法表明它应该通过在每一步 "two forward, one back" 生成子列表。
然后您可以简单地使用 .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)
法线映射将函数应用于列表元素并生成结果列表的元素。例如,如果列表是 (1, 2, 3,)
并映射平方函数,您将得到一个新列表 (1, 4, 9,)
.
有没有办法映射列表的一组顺序元素?例如,如果列表是 <8 2 7 2 6 9 4 9 6 1>
并且我想计算列表中每 2 个元素的总和以使 <10 9 9 8 15 13 13 15 7>
?
我当然可以写一个遍历列表的例程。但我正在寻找一种更简单的方法,例如缩减运算符或 gather/take。
执行此操作的函数式编程方法是引用列表两次,将一个版本偏移一个元素,然后将它们压缩在一起。这为您提供了后续元素的所有元组。
my @l := <a b c d e f>;
say @l Z @l[1..*]; # output: ((a b) (b c) (c d) (d e) (e f))
如果您不想创建一个临时变量来保存列表,请使用 given
(如果您需要 return 一个值的语句,请使用 do given
):
given <8 2 7 2 6 9 4 9 6 1> {
say ($_ Z $_[1..*]).map: -> [$a, $b] { $a+$b };
}
如果您使用的函数带有两个参数,您可能希望在压缩后展平列表并让 map
一次带两个元素:
given <8 2 7 2 6 9 4 9 6 1> {
say ($_ Z $_[1..*]).flat.map(&infix:<+>);
}
您可以使用 .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))
2 => -1
是一个 Pair
参数,它向方法表明它应该通过在每一步 "two forward, one back" 生成子列表。
然后您可以简单地使用 .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)