Is there any way to rewrite this more elegant? I think, that it's a bad piece of code and should be refactored.
>> a = [2, 4, 10, 1, 13]
=> [2, 4, 10, 1, 13]
>> index_of_minimal_value_in_array = a.index(a.min)
=> 3
Is there any way to rewrite this more elegant? I think, that it's a bad piece of code and should be refactored.
>> a = [2, 4, 10, 1, 13]
=> [2, 4, 10, 1, 13]
>> index_of_minimal_value_in_array = a.index(a.min)
=> 3
It would be interesting to read about other situations (finding all and only last minimal element).
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
each.with_index
takes the array and adds an index to it making a array of arrays, with the inner arrays containing the original elements plus indexes. Then you can pass that to other transformers like map
. each_with_index
wants to iterate over the arrays of arrays. It's a subtle difference but I didn't want an each
loop, I wanted to transform. –
Laurenalaurence I believe this will traverse the array only once and is still easy to read:
numbers = [20, 30, 40, 50, 10] # => [20, 30, 40, 50, 10]
elem, idx = numbers.each_with_index.min # => [10, 4]
Array#last
makes it ugly (ary.each_with_index.min.last
). –
Furlong ary.each_with_index.min.second
is prettier. –
Phlegm This traverses the array only once whereas ary.index(ary.min)
would traverse it twice:
ary.each_with_index.inject(0){ |minidx, (v,i)| v < a[minidx] ? i : minidx }
ary.each_with_index.inject([Float::INFINITY,0]) { |(mv,mi), (v,i)| v<mv ? [v,i] : [mv,mi] }
–
Hexahedron It would be interesting to read about other situations (finding all and only last minimal element).
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
each.with_index
takes the array and adds an index to it making a array of arrays, with the inner arrays containing the original elements plus indexes. Then you can pass that to other transformers like map
. each_with_index
wants to iterate over the arrays of arrays. It's a subtle difference but I didn't want an each
loop, I wanted to transform. –
Laurenalaurence I actually like @andersonvom 's answer, it only need to loop the array once and still get the index.
And in case you don't want to use ary.each_with_index.min
, here is what you can do:
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
© 2022 - 2024 — McMap. All rights reserved.