在Raku地图代码/块中访问callee/this



是否可以访问" calle"("this")在Raku地图代码块和/或任何代码?

。如果要计算算术平均值

my $data = <1 10 0 7 2> ;
say $data.sum
/ $data ;   # or @$data, same as $data.elems in this numeric context
# OUTPUT: «4␤»

通过分数和

say $data.map(* / $data).sum
# OUTPUT: «4␤»

<1 10 0 7 2>.map({ $_ / $this }).sum   # but there's no $this

<1 10 0 7 2>.map( * / $this ).sum

如果没有,是否有一种习惯的方法来做到这一点,只有一个链的方法调用<…>数据字面量,或不同的方式,不存储在变量中的数据?

据我所知没有。你需要知道迭代器将产生多少个值。

在引擎盖下,foo.map: &callable基本上是一个:

my $iterator = foo.iterator;
callable($iterator.pull-one) until iterator exhausted;

注意,所有关于迭代器源的知识在这里都丢失了:只有一个迭代器产生值。

某些类型的迭代器(所谓的PredictiveIterators)可以告诉您它在不实际生成值的情况下仍然可以生成多少值。但大多数迭代器都做不到这一点。

我想从技术上讲,map可以检查它是否得到了PredictiveIterator,并设置一个动态变量,它将产生的值的数量,然后您可以在&callable内检查。

仍然觉得不值得为所有进行额外检查maps和for循环,所以我不认为这种功能的PR会被接受。

你可以这样做,通过andthen

<1 10 0 7 2>
andthen .sum / .elems
andthen .say

<1 10 0 7 2>
andthen .map: * / .elems
andthen .sum
andthen .say

正如Liz提到的,没有自动绑定到要迭代的值的变量,但是有几种方法可以实现您想要的。通过将系列绑定到topic变量,有三种方法可以做到这一点(第一种方法最简洁,可能是我要写的):

<1 10 0 7 2>.&{ .map(* / $_).sum };
given <1 10 0 7 2> { .map(* / $_).sum };
with <1 10 0 7 2> { .map(* / $_).sum };

另一个选择是用xx复制初始列表。这里有一种方法,尽管我不太喜欢这种方法。

(<1 10 0 7 2> xx 2).map({|$^a.map: * / $_}).sum;

类似地,您可以将列表中的每个元素作为一个整体压缩(在这个简单的情况下,这可能是多余的,但在类似的情况下可能很有用。)

最新更新