在 Raku 的内部循环中使用循环的位置参数

Lar*_*een 5 loops positional-parameter raku

这是代码:

my @s=<a b c d>;
for @s.kv {
    for ($^k ... @s.elems) {
        printf("%s ", $^v);
    }
    printf("\n");
}
Run Code Online (Sandbox Code Playgroud)

预期输出为:

# a b c d
# b c d
# c d
# d
Run Code Online (Sandbox Code Playgroud)

但它给出了这个错误(可能等等)

key 0, val 1 Too few positionals passed; expected 2 arguments but got 1
Run Code Online (Sandbox Code Playgroud)

它看起来像主循环的位置的变量$^k,并$^v不能在内环内使用。如何解决?谢谢。更新:修复了内循环内的错字

Sci*_*mon 6

所以对于你想做的事情,我会这样处理:

my @s = <a b c d>;
for ^@s.elems -> $start-index {
    for @s[$start-index..*] -> $value {
        printf("%s ", $value );
    }
    print("\n");
}
Run Code Online (Sandbox Code Playgroud)

虽然我真的会这样做。

my @s = <a b c d>;
(^@s.elems).map( { @s[$_..*].join(" ").say } )
Run Code Online (Sandbox Code Playgroud)

获取从 0 到数组中元素数的范围。然后从那里到每个切片,加入空格并说。

有关$^k此类变量的注释仅适用于当前块(因此您的上述代码不起作用)。通常你只有真正想使用它们mapgrep或其他类似的东西。在可能的情况下,我总是建议命名您的变量,这也使它们的作用域也位于内部块内。

  • `@s[$_..*].join(" ").say for ^@s` &lt;-- 一点高尔夫,希望被认为是优雅的。LarsMalmsteen,“^”作为前缀将其操作数强制为数字,因此“^@s”是“^@s.elems”的快捷方式(这是“0..^@s.elems”的快捷方式) 。我在脑海中将 `^foo` 读为“直到 `foo`”,更精确的扩展是“从零到*但不包括* `foo`”。因此,如果 `@s` 中有 4 个元素,那么 `^@s` 与 `^4` 相同,它迭代到 `0, 1, 2, 3`。 (3认同)

jjm*_*elo 6

Scimon Proctor 的回答基本上是正确的,但我会尝试解释为什么你的例子不起作用。对于初学者,kv返回“索引和值的交错序列”,因此:

my @s=<a b c d>;
.say for @s.kv;
Run Code Online (Sandbox Code Playgroud)

印刷

0
a
1
b
2
c
3
d
Run Code Online (Sandbox Code Playgroud)

本质上,您正在为每个键值执行一次循环。使用rotor将它们成对分组可能更接近您要查找的内容:

.say for @s.kv.rotor(2)
Run Code Online (Sandbox Code Playgroud)

这将返回:

(0 a)
(1 b)
(2 c)
(3 d)
Run Code Online (Sandbox Code Playgroud)

因为有了这个我们得到了索引的值,我们可以做......

my @s=<a b c d>;
for @s.kv.rotor(2) -> ($k, $) {
    "{@s[$_]} ".print for ($k..^@s.elems);
    printf("\n");
}
Run Code Online (Sandbox Code Playgroud)

请注意,内部循环中也存在错误,其范围超出了@s 中的实际索引。但是,再次,Scimon 使用地图的答案要短得多、惯用语和直接。这只是一种降低您的原始程序的方法。事实上,我们正在丢弃这些值,所以这实际上是:

my @s=<a b c d>;
for @s.keys -> $k {
    "{@s[$_]} ".print for ($k..^@s.elems);
    printf("\n");
}
Run Code Online (Sandbox Code Playgroud)

根本不需要使用 kv ,只需使用keys

  • 或者,对于“rotor”示例,可以让块的签名抓取,但是每轮循环都需要许多参数(例如,“for @s.kv -&gt; $k, $ { ... }”)。一如既往,TIMTOADY 不过;-)! (2认同)