在 Raku 的内部循环中使用循环的位置参数
Posted
技术标签:
【中文标题】在 Raku 的内部循环中使用循环的位置参数【英文标题】:Using a loop's positional parameters inside an inner loop in Raku 【发布时间】:2020-04-25 01:27:00 【问题描述】:代码如下:
my @s=<a b c d>;
for @s.kv
for ($^k ... @s.elems)
printf("%s ", $^v);
printf("\n");
预期输出是:
# a b c d
# b c d
# c d
# d
但它给出了这个错误(可能还有其他错误)
key 0, val 1 Too few positionals passed; expected 2 arguments but got 1
看起来主循环$^k
和$^v
的位置变量不能在内循环内部使用。如何解决?谢谢。
更新:内循环内的错字已修复
【问题讨论】:
预期输出 100% 与您的打印语句不匹配。($^k...@s.elems)
也给你索引而不是值。
操作。这是我的笔记留下的。更新了该部分。
【参考方案1】:
所以对于你想做的事情,我会这样处理:
my @s = <a b c d>;
for ^@s.elems -> $start-index
for @s[$start-index..*] -> $value
printf("%s ", $value );
print("\n");
虽然我真的会这样做。
my @s = <a b c d>;
(^@s.elems).map( @s[$_..*].join(" ").say )
获取从 0 到数组中元素个数的范围。然后每个切片从那里到最后,加入空格并说。
关于$^k
等变量的注释仅适用于当前块(因此您的上述代码无法正常工作)。一般来说,你只是真的想在map
、grep
或其他类似的东西中使用它们。在可能的情况下,我总是建议命名你的变量,这使得它们也被限制在内部块中。
【讨论】:
感谢您的回答。^@s.elems
前面的^
是怎么操作的?
这是 0..^@s.elems 范围的捷径。 (你不想要 @s.elems 本身,因为这超出了界限)。
@s[$_..*].join(" ").say for ^@s
^ 作为前缀将其操作数强制为数字,因此^@s
是^@s.elems
的快捷方式(0..^@s.elems
的快捷方式)。我在脑海中将^foo
读作“直到foo
”,更精确的扩展是“从零到但不包括 foo
”。所以如果@s
中有4个元素,那么^@s
和^4
一样,会迭代到0, 1, 2, 3
。
@ScimonProctor 添加的最后一段关于为什么$^k
变量不起作用非常有帮助。两种单线解决方案(由@ScimonProctor 和@raiph 提供)都有助于学习真正的语言。至于^
操作符的用法,我其实也知道,但不知怎的,我就忘记了。我将通过它的解释,它们对我很有价值。谢谢。【参考方案2】:
Scimon Proctor 的回答基本上是正确的,但我会尝试解释为什么您的示例不起作用。对于初学者,kv
返回“索引和值的交错序列”,因此:
my @s=<a b c d>;
.say for @s.kv;
打印
0
a
1
b
2
c
3
d
本质上,您正在为每个键 和 值执行一轮循环。使用rotor
将它们成对分组可能更接近您要查找的内容:
.say for @s.kv.rotor(2)
将返回:
(0 a)
(1 b)
(2 c)
(3 d)
因为有了这个我们得到了值和索引,我们可以这样做......
my @s=<a b c d>;
for @s.kv.rotor(2) -> ($k, $)
"@s[$_] ".print for ($k..^@s.elems);
printf("\n");
请注意,内部循环中也存在错误,其范围超出了@s 中的实际索引。但是,同样,Scimon 使用地图的答案要短得多、惯用且直截了当。这只是在缩小您的原始程序。事实上,我们正在丢弃这些值,所以这实际上是:
my @s=<a b c d>;
for @s.keys -> $k
"@s[$_] ".print for ($k..^@s.elems);
printf("\n");
根本不需要使用kv,只需使用keys即可。
【讨论】:
@raiph 实际上有更好的方法,我只是编辑了它。但你是对的,一如既往,谢谢。 @jmerelo :) :) :) 很高兴看到.kv
构造不起作用的解释。将 .kv
与 `rotor 一起使用也是一个好主意。
另外,对于rotor
示例,可以让块的签名抓取,但是循环的每一轮都需要许多参数(例如,for @s.kv -> $k, $ ...
)。一如既往,虽然 TIMTOADY ;-)!以上是关于在 Raku 的内部循环中使用循环的位置参数的主要内容,如果未能解决你的问题,请参考以下文章