在数组中找到所有最大元素的索引

3

我有一个如下的数组:

vals = [1,2,10,5,10,5,9,10]

我需要获取数组中最大元素的索引(在上面的例子中是10)。因此,在我的例子中,它应该输出另一个数组:[2, 4, 7]。但是,当我使用带有块的#find_index时,我只能得到第一个匹配的索引:
[12] pry(main)> vals.find_index { |i| i == vals.max }
=> 2

我可以通过这种方法获得我想要的东西,但它似乎有些啰嗦:
[14] pry(main)> results = []
=> []
[15] pry(main)> vals.each_with_index do |elem, i|
[15] pry(main)*   results << i if elem == vals.max
[15] pry(main)* end
=> [1, 2, 10, 5, 10, 5, 9, 10]
[16] pry(main)> results
=> [2, 4, 7]

有没有更符合 Ruby 风格的方法来完成这个任务呢?


1
对于数组中的每个元素调用 vals.max 不是一个好的方案。这会导致每次都要遍历整个数组,因此时间复杂度为 O(N^2)。 - tadman
非常好的观点 @tadman - 我可以将max值存储在自己的变量中以进行比较。 - Anthony
4个回答

3

虽然有点混乱,但你可以做到这一点:

vals = [ 1,2,10,5,10,5,9,10 ]
val_max = vals.max

result = vals.each_with_index.each_with_object([ ]) do |(v,i),a|
  a << i if (v == val_max)
end

# => [ 2, 4, 7 ]

2
两个微不足道的选择:只需使用.with_object或者vals.each_with_object([ ]).with_index,并且使用块变量|(v,a),i| - Cary Swoveland
@CarySwoveland 不错的优化。 - tadman

3
vals = [1, 2, 10, 5, 10, 5, 9, 10]
max = vals.max

vals.map.with_index {|n, i| i if n == max }.compact
# => [2, 4, 7] 

3

试试这个:

vals = [1, 2, 10, 5, 10, 5, 9, 10]
max_val = vals.max

vals.each_index.select{|i| vals[i] == max_val}

注意:答案来源于查找与给定条件匹配的元素索引


注:此处为提示信息,来源于某个网站关于在Ruby中查找与给定条件匹配的元素索引的问题。

...但无论如何,你都会想到的。在我看来,这是最好的方式。 - Cary Swoveland
我真的很喜欢这个 - 非常 Ruby! - Anthony

0
如果你想避免两次遍历(即一次获取max_val,然后再次遍历列表):
vals    = [ 1,2,10,5,10,5,9,10 ]
max_val = vals.first - 1
indices = []

vals.each_with_index do |n, idx|
  if n < max_val
    # Do nothing, but common case, so avoid second comparison
  elsif n == max_val
    indices << idx
  elsif n > max_val
    max_val = n
    indices = [ idx ]
  end
end

indices

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接