Reputation: 29
What is the appropriate method to get the sum of the two largest values in array using Ruby?
I know array.sort
and array.max
and inject(:+)
but I don't know how to combine them.
Upvotes: 1
Views: 6144
Reputation: 160551
It's always good to have some benchmarks to see what is the fastest way to accomplish something:
require 'active_support/core_ext/enumerable'
require 'fruity'
ARRAY = (0..1000).to_a.shuffle
compare do
adriano { ARRAY.max(2).reduce(:+) }
mori { ARRAY.sort.last(2).sum }
edgars { ARRAY.sort[-2..-1].inject(:+) }
end
# >> Running each test 64 times. Test will take about 1 second.
# >> adriano is faster than edgars by 50.0% ± 10.0%
# >> edgars is similar to mori
Upvotes: 1
Reputation:
You could try something like this
array = [13, 2, 21, 36, 4, 9]
array.reverse.first(2).reduce(:+)
In this method we are reverse sorting the array, which is sorting it from highest to lowest. This puts the largest numbers first in the array. reduce
method returns the sum of these numbers. In this case, the sum of 36 and 21 is 57.
57
Upvotes: 1
Reputation: 330
I would strongly favor the simpler and faster:
array.max(2).reduce(:+)
Sorting is unnecessary, it is enough to scan the array updating a max-heap of size K. Using Array#max(K)
you achieve O(N x log(K)) asymptotic time complexity versus O(N x log(N)) of sorting.
Upvotes: 6
Reputation: 2853
[1,2,3,4].sort[-2..-1].inject(:+)
If you are looking for a more efficient solution, you will be better with this one:
[1,2,3,4].inject([0, 0]) do |largest, el|
if largest[0] < el
largest[1] = largest[0]
largest[0] = el
elsif largest[1] < el
largest[1] = el
end
largest
end.inject(:+)
If you are familiar with algorithm complexity, than you can see that the first one is nlogn
to n^2
, depending on the Ruby sorting algorithm, where the second solution is just n
as it goes through the array once.
Upvotes: 2