我考虑过这些方法在红宝石中的不同之处。我知道,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
时给我一些例子吗?
答案 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
快得多。以下是detect
和select
的基准测量。
detect: 0.000000 0.000000 0.000000 ( 0.000010)
select: 0.740000 0.010000 0.750000 ( 0.753949)