perl6什么是取消选择数组或列表元素的快速方法? [英] perl6 What is a quick way to de-select array or list elements?

查看:81
本文介绍了perl6什么是取消选择数组或列表元素的快速方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要在perl6中从数组中选择多个元素,很容易:只需使用索引列表即可。

To select multiple elements from an array in perl6, it is easy: just use a list of indices:

> my @a = < a b c d e f g >;
> @a[ 1,3,5 ]
(b d f)

但要取消选择这些元素,我不得不使用Set:

But to de-select those elements, I had to use Set:

> say @a[ (@a.keys.Set (-) (1,3,5)).keys.sort ]
(a c e g)

我想知道是否有更简单的方法,因为我使用的数组通常很大?

I am wondering if there is an easier way because the arrays I use are often quite large?

推荐答案

sub infix:<not-at> ($elems, @not-ats) {
  my $at = 0;
  flat gather for @not-ats -> $not-at {
    when $at < $not-at { take $at++ xx $not-at - $at } 
    NEXT { $at++ }
    LAST { take $at++ xx $elems - $not-at - 1 }
  }
}

my @a = < a b c d e f g >;
say @a[ * not-at (1, 3, 5) ]; # (a c e g)

如果您知道每个P6构造,我认为操作员代码是不言自明的它用。如果有人喜欢下面的解释,请在评论中让我知道。

I think the operator code is self-explanatory if you know each of the P6 constructs it uses. If anyone would appreciate an explanation of it beyond the following, let me know in the comments.

我将从产生<$ c调用的两个方面开始$ c>不存在。

来自 任何内容文档页面

From the Whatever doc page:


* 用在术语位置,即作为操作数,与大多数运算符结合使用,编译器会将表达式转换为 WhateverCode

When * is used in term position, that is, as an operand, in combination with most operators, the compiler will transform the expression into a closure of type WhateverCode

* 确实在上面用作操作数。在这种情况下,我的中缀 not-at 运算符的左参数(与 $ elems 参数相对应)

* is indeed used in the above as an operand. In this case it's the left argument (corresponding to the $elems parameter) of the infix not-at operator that I've just created.

下一个问题是,编译器会进行转换吗?编译器根据运算符是否具有显式 * 作为与 * 参数相对应的参数来进行决策。如果我写的是 * 而不是 $ elems ,那么就不会希望直接处理 * 并执行其选择的操作的少数运算符之一,编译器将直接调用它。但是我没有。我写了 $ elems 。因此,编译器将执行我将在下面描述的转换。

The next question is, will the compiler do the transform? The compiler decides based on whether the operator has an explicit * as the parameter corresponding to the * argument. If I'd written * instead of $elems then that would have made not-at one of the few operators that wants to directly handle the * and do whatever it chooses to do and the compiler would directly call it. But I didn't. I wrote $elems. So the compiler does the transform I'll describe next.

转换将构建新的 WhateverCode 括起来,并将 Whatever 重写为 it aka主题,也称为 $ _ 。因此,在这种情况下,它变成这样:

The transform builds a new WhateverCode around the enclosing expression and rewrites the Whatever as "it" aka the topic aka $_ instead. So in this case it turns this:

* not-at (1,3,5)

为此:

{ $_ not-at (1,3,5) }



什么 [ ...] 作为下标



其中的 [...] @a [...] Postional (数组/列表)的下标。这强加了几个评估方面,其中两个问题在这里:

What [...] as a subscript does

The [...] in @a[...] is a Positional (array/list) subscript. This imposes several evaluation aspects, of which two matter here:


  • it又名主题 $ _ 设置为列表/数组的长度。

  • "it" aka the topic aka $_ is set to the length of the list/array.

如果下标的内容为 Callable 它被调用。如上所述生成的 WhateverCode 确实是 Callable ,因此它被调用。

If the content of the subscript is a Callable it gets called. The WhateverCode generated as explained above is indeed a Callable so it gets called.

所以这:

@a[ * not-at (1,3,5) ]

变为:

@a[ { $_ not-at [1,3,5] } ]

变成这样:

 @a[ { infix:not-at(7, [1,3,5]) } ]

这篇关于perl6什么是取消选择数组或列表元素的快速方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆