在Perl 6中过滤与两个正则表达式匹配的元素

时间:2018-09-30 09:23:23

标签: perl6

这里发生的事情我不太了解。

> my @arr = <ac bc abc>
> @arr.grep: (( * ~~ /a/ ) && ( * ~~ /b/ ))
(bc abc)

但是

> @arr.grep(* ~~ /a/).grep(* ~~ /b/)
(abc)

是什么原因?

1 个答案:

答案 0 :(得分:8)

您已经提出了完美的解决方案。

另一个可能是:

my @arr = <ac bc abc>
@arr.grep: { $_ ~~ /a/ && $_ ~~ /b/ }
(abc)

此答案的其余部分仅说明了问题。此问题中的问题是WhateverStar && WhateverStar中涵盖的问题的更复杂版本。


如果逻辑操作是代码,则逻辑操作不会执行其参数。

所以{ $_ ~~ /a/ } && { $_ ~~ /b/ }返回{ $_ ~~ /b/ }

或者* ~~ /a/ && * ~~ /b/返回* ~~ /b/

同时,grep 执行如果它是代码或正则表达式,则执行其匹配器,因此它们都是相同的:

foo.grep: { $_ ~~ /.../ }
foo.grep:    * ~~ /.../;
foo.grep:         /.../;

Junction的魔力

您的Junction解决方案似乎很自然。如果有人可以在下面解释我的缺失,我将非常乐意。当我期望可以正常工作时,我很想知道它是如何工作的,但是我认为它有点像(但不太完全):

  • foo & bar成为Junction foo的{​​{1}}。

  • 试图使用bar作为参数来调用grep

  • 由于Junction在常规Junction值层次结构之外,因此大多数例程没有匹配的签名。 Any没有。

  • 当您调用例程并且没有相应的签名时,初始调度将失败,我们将遇到调度回退处理程序。 This可能是方法之一。

  • 如果调度后备处理程序看到有grep个参数,则它将提取Junction中的各个值,并触发逻辑上并行的“线程”(当前从不 actual 线程,但是如果编译器认为这是一个不错的主意,允许它们使其成为真实的线程(对应于这些值)。因此,它会对发起方的每个元素调用Junction两次,并将结果输出到与传入grep相同类型的新Junction中。

  • 在布尔上下文中,Junction折叠为单个结果。

  • (如果Junction在整个布尔上下文中,则它可以基于结果(并行)短路。如果它是Junction any 结果出现在any中,那么它可以取消其余部分-或者如果它实际上是按顺序执行操作,则可以不首先执行它们,就像目前通常这样。如果是True并且有任何结果在all中可以取消其他内容。