您的代码需要一个 eon 来执行,因为它正在为每个元素执行 count,导致它的计算复杂度为 O(n2)。
arr = [*1..35000, 1, 34999]
如果您想知道哪些值至少出现在数组中两次...
require 'set'
uniq_set = Set.new
arr.each_with_object(Set.new) { |x,dup_set| uniq_set.add?(x) || dup_set.add(x) }.to_a
#=> [1, 34999]
集合查找(在后台使用哈希实现)非常快。
请参阅 Set#add? 和 Set#add。
如果您想知道值在数组中出现至少两次的次数...
arr.each_with_object(Hash.new(0)) { |x,h| h[x] += 1 }.select { |_,v| v > 1 }
#=> {1=>2, 34999=>2}
这使用了一个计数哈希1。当它采用 默认值 作为参数时,请参阅 Hash::new。
如果您想知道数组中至少出现两次的值的索引...
arr.each_with_index.
with_object({}) { |(x,i),h| (h[x] ||= []) << i }.
select { |_,v| v.size > 1 }
#=> {1=>[0, 35000], 34999=>[34998, 35001]}
当哈希h还没有密钥x时,
(h[x] ||= []) << i
#=> (h[x] = h[x] || []) << i
#=> (h[x] = nil || []) << i
#=> (h[x] = []) << i
#=> [] << i where [] is now h[x]
1. Ruby v2.7 给了我们方法Enumerable#tally,让我们可以写arr.tally.select { |_,v| v > 1 }。