我在 rosettacode 遇到了这个代码
my @pascal = [1], { [0, |$_ Z+ |$_, 0] } ... Inf;
.say for @pascal[^4];
# ==>
# [1]
# [1 1]
# [1 2 1]
# [1 3 3 1]
在显式生成器块中,我知道单个运算符如何喜欢列表扁平化
|
和 zip 运算符 Z+
工作,但我很难理解他们如何合作生成下一个数组。有人可以详细解释它是如何工作的吗?谢谢你。注意:为简洁起见,代码略有重新排列,即它与 Rosetta 中的代码在表面上有所不同。
最佳答案
这是序列运算符的一个有点有趣的应用,因为它每次产生的值都是数组。所以:
[1]
是在序列 Inf
永远不会匹配,所以序列将永远继续 一个更简单的例子可能会有所帮助:序列
[1], [1,1], [1,1,1], ...
.也就是说,我们想要生成一个数组,它是序列中的前一项,并带有额外的 1
在末尾。我们可以这样做:my @ones = [1], { [|$_, 1] } ... Inf;
.say for @ones[^4];
生产:
[1]
[1 1]
[1 1 1]
[1 1 1 1]
第一次调用块时,它得到
[1]
在 $_
.我们通过 |
忽略了这一点,从而产生一个数组 [1, 1]
.第二次将其传递给块,依此类推。所以,分解
[0, |$_ Z+ |$_, 0]
.外方括号是一个数组组合器。其余的可以读为0, |$_
zipper |$_, 0
,使用 +
运算符(operator)来压缩东西。第一个被阻塞的调用将通过
[1]
,因此我们将压缩 0, 1
和 1, 0
.使用运算符压缩成对应用,这意味着它将计算 0 + 1, 1 + 0
.整体结果是数组 [1,1]
.对该块的第二次调用得到
[1,1]
.它形成列表 0, 1, 1
和 1, 1, 0
,然后 zip 运算符再次形成成对加法,即 0 + 1, 1 + 1, 1 + 0
.整体结果是数组 [1,2,1]
.那么,实际上,结果每次都会增加一个元素,这是由于前一个结果的两两相加在两端用零填充。
关于sequence - 关于Raku中数组生成序列的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58976848/