Perl 6:检查元素是否在列表中的最佳方法是什么? [英] Perl 6: what's the best way to check if an element is in a list?

查看:48
本文介绍了Perl 6:检查元素是否在列表中的最佳方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个大数组 @stuff 和一个 $thing,我想知道 $thing 是否在@stuff.在 Perl 6 中做到这一点的最佳方法是什么?最好"的意思是:惯用的、可读的、高效的;不一定按这个顺序.

实际上有两种不同的情况.一种是你必须对不同的 $thing 进行大量检查,另一种是你只做一次或几次.

我们先来看第一种情况.我想我知道(或一个)正确答案.

my $set-of-stuff = set @stuff;对于@whatever ->$东西{do-something-with($thing) 如果 $thing ∈ $set of stuff;}

您实际上可以跳过第一行并简单地说 ... if $thing ∈ @stuff,但这几乎肯定会导致性能更差,因为每次都会创建集合.

但现在是第二种情况,我只有一个 $thing 需要检查.上面的解决方案当然有效,但是创建集合,只是为了检查一次,似乎有很多开销.捷径

do-something-with($thing) if $thing ∈ @stuff;

在这里更有意义,因为我们只调用一次.但是,我们仍然必须创建一个一次性使用的集合.

更传统的一点是:

do-something-with($thing) if @stuff.grep($thing);

或者可能更快:

do-something-with($thing) if @stuff.first($thing);

但这似乎不太习惯,当然第二个比 $thing ∈ @stuff 可读性差.

我认为没有智能匹配解决方案,对吗?这当然行不通:

do-something-with($thing) if $thing ~~ @stuff;

有什么想法吗?

解决方案

取决于您对最佳"或智能"的定义.

如果你在谈论性能,我很确定

@stuff.first($thing)

是最快的.

惯用地,接近上述解决方案,将是:

$thing ~~ 任何@stuff

由于自动线程化,它具有更好的挂钟性能的潜力.

使用集合来做到这一点,使代码看起来更接近形式逻辑.但它不会使事情更快,因为需要创建集合(除非它可以在编译时创建).

不确定这个答案是否有最佳"答案.

Let's say I have a large array, @stuff, and a $thing, and I want to know if $thing is in @stuff. What's the best way to do that in Perl 6? And with "best" I mean: idiomatic, readable, performant; not necessarily in that order.

There are actually two separate cases. One is where you have to do a lot of checks for different $things, the other is where you only do this once or a few times.

Let's look at the first case first. I think I know the (or a) right answer.

my $set-of-stuff = set @stuff;
for @whatever -> $thing {
    do-something-with($thing) if $thing ∈ $set of stuff;
}

You can actually skip the first line and simply say ... if $thing ∈ @stuff, but that will almost certainly have much worse performance, since the set is created every time.

But now the second case, I only have one $thing to check. The above solution works, of course, but creating the set, just to check it once, seems a lot of overhead. The shortcut

do-something-with($thing) if $thing ∈ @stuff;

makes a little more sense here, since we only call it once. But still, we have to create a set for one use.

A bit more traditional is:

do-something-with($thing) if @stuff.grep($thing);

Or potentially faster:

do-something-with($thing) if @stuff.first($thing);

But this seems less idiomatic, and certainly the second one is less readable than $thing ∈ @stuff.

I don't think there's a smart match solution, right? Certainly this doesn't work:

do-something-with($thing) if $thing ~~ @stuff;

Any thoughts?

解决方案

Depends on what your definition of "best" or "smart" is.

If you're talking about performance, I'm pretty sure

@stuff.first($thing)

is the fastest.

Idiomatically, and close to the above solution, would be:

$thing ~~ any @stuff

which has the potential of better wallclock performance due to auto-threading.

Using sets to do this, makes the code look closer to formal logic. But it won't make things faster, because the set needs to be created (unless maybe it could be created at compile time).

Not sure there is a "best" answer to this one.

这篇关于Perl 6:检查元素是否在列表中的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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