Ruby: Как найти индекс минимального элемента массива? - PullRequest
18 голосов
/ 11 февраля 2011

Есть ли способ переписать это более элегантно? Я думаю, что это плохой кусок кода и должен быть реорганизован.

>> a = [2, 4, 10, 1, 13]
=> [2, 4, 10, 1, 13]
>> index_of_minimal_value_in_array = a.index(a.min)
=> 3

Ответы [ 4 ]

39 голосов
/ 04 ноября 2012

Я полагаю, что это будет проходить массив только один раз и все еще легко читается:

ary = [2,3,4,5,1]        # => [2,3,4,5,1]
ary.each_with_index.min  # => [1, 4]
                         # where 1 is the element and 4 is the index
8 голосов
/ 22 ноября 2011

Это обходит массив только один раз, тогда как ary.index(ary.min) будет пересекать его дважды:

ary.each_with_index.inject(0){ |minidx, (v,i)| v < a[minidx] ? i : minidx }
6 голосов
/ 11 февраля 2011

Было бы интересно почитать о других ситуациях (найти все и только последний минимальный элемент).

ary = [1, 2, 1]

# find all matching elements' indexes
ary.each.with_index.find_all{ |a,i| a == ary.min }.map{ |a,b| b } # => [0, 2]
ary.each.with_index.map{ |a, i| (a == ary.min) ? i : nil }.compact # => [0, 2]

# find last matching element's index
ary.rindex(ary.min) # => 2
3 голосов
/ 22 апреля 2015

Мне действительно нравится ответ @andersonvom, нужно только один раз зациклить массив и получить индекс.

А если вы не хотите использовать ary.each_with_index.min, вот чтоможно сделать:

ary = [2,3,4,5,1]                                             # => [2,3,4,5,1]
_, index_of_minimal_value_in_array = ary.each_with_index.min  # => [1, 4]
index_of_minimal_value_in_array                               # => 4
...