在 Raku 的内部循环中使用循环的位置参数
Using a loop's positional parameters inside an inner loop in Raku
代码如下:
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
的位置变量不能在内循环中使用。如何解决?谢谢。
更新:内部循环内的拼写错误已修复
所以对于你想做的事情,我会这样处理:
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
或其他类似的地方使用它们。在可能的情况下,我总是建议命名您的变量,这也会使它们在内部块中起作用。
Scimon Proctor 的回答基本上是正确的,但我会尝试解释为什么您的示例不起作用。对于初学者,kv
returns "an interleaved sequence of indexes and values",因此:
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)
这将 return:
(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。
代码如下:
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
的位置变量不能在内循环中使用。如何解决?谢谢。
更新:内部循环内的拼写错误已修复
所以对于你想做的事情,我会这样处理:
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
或其他类似的地方使用它们。在可能的情况下,我总是建议命名您的变量,这也会使它们在内部块中起作用。
Scimon Proctor 的回答基本上是正确的,但我会尝试解释为什么您的示例不起作用。对于初学者,kv
returns "an interleaved sequence of indexes and values",因此:
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)
这将 return:
(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。