在 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 等变量的注释仅适用于当前块(因此您的上述代码无法正常工作)。一般来说,你只是真的想在mapgrep 或其他类似的东西中使用它们。在可能的情况下,我总是建议命名你的变量,这使得它们也被限制在内部块中。

【讨论】:

感谢您的回答。 ^@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 -&gt; $k, $ ... )。一如既往,虽然 TIMTOADY ;-)!

以上是关于在 Raku 的内部循环中使用循环的位置参数的主要内容,如果未能解决你的问题,请参考以下文章

bash:for 循环与位置参数( $*$@)

python 11 函数名 迭代器

Python ❀ 函数

5,v-for循环

Python ❀ 函数

请问这个python脚本哪里出错了?打印出一个无限循环的数