差异beetwen detect {}并选择{} [0]

时间:2016-09-08 15:00:04

标签: arrays ruby

我考虑过这些方法在红宝石中的不同之处。我知道,select返回一个元素数组,detect只返回一个和第一个consisten元素。但如果我输入array.select{ condition }[0],有什么不同吗?它将返回第一个单位,如detect。 例如:

a = [2,3,4,5]
a.detect{|k| k.even? }
# => 2
a.select{|k| k.even? }[0]
# => 2

任何人都可以向我解释这些方法的其他区别,并在detect优于select时给我一些例子吗?

3 个答案:

答案 0 :(得分:4)

当您只需要检索一个项目时,detect更可取,因为它会在找到与条件匹配的第一个匹配项时停止迭代数组。因为select检索与条件匹配的所有匹配项,所以它必须迭代整个列表。在最坏的情况下(匹配条件的项目不在列表中)这些是等价的,但如果您要查找的项目在列表的早期detect将更具性能。

答案 1 :(得分:4)

我会在这里发布一个例子,恕我直言会澄清一切:

(1..Float::INFINITY).detect &:odd?
#⇒ 1
(1..Float::INFINITY).select(&:odd?).first
#⇒ :(

答案 2 :(得分:1)

差异是detect将返回块评估为true的第一个值,在这种情况下,它是数字2。如果您只想从数组中获取一个值,则速度会更快,因为在找到一个返回true的值后,它不会评估数组的其余部分。

select将返回基于块返回true的每个元素,因此它将返回[2,4]select将为每个元素评估块,因此它比detect慢。

根据您在示例中所做的操作,您只选择select返回的第一个元素,最好使用detect

这方面的一个很好的例证就是说,你有1000万件物品的数组,随机数从0到100万。

arr = Array.new(1_000_000) { rand(1_000_000) }

如果您只想返回第一个偶数,则在此值中使用detect将比select快得多。以下是detectselect的基准测量。

detect:  0.000000   0.000000   0.000000 (  0.000010)
select:  0.740000   0.010000   0.750000 (  0.753949)