2014-11-21 117 views
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] 

有沒有人有一個更紅寶石般的方式任何想法做到這一點?

+1

爲數組中的每個元素調用'vals.max'並不是一個好計劃。每次都必須爲每個元素旋轉數組,所以你在那裏是O(N^2)。 – tadman 2014-11-21 15:31:05

+0

非常好的一點@tadman - 我可以將它的最大值存儲在它自己的變量中用於比較。 – Anthony 2014-11-21 15:32:56

回答

3

試試這個:

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

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

注:答案從Find indices of elements that match a given condition

+0

...但無論如何你會想到它。最好的方法,imo。 – 2014-11-21 18:08:49

+0

我真的很喜歡這個 - 非常紅寶石! – Anthony 2014-11-21 22:55:02

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 |'。 – 2014-11-21 18:19:04

+0

@CarySwoveland尼斯優化。 – tadman 2014-11-21 19:27:47

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] 
0

derrived如果您希望避免兩次傳球(即, .E。一個獲得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