Fravadona
Fravadona

Reputation: 17198

Ruby array: getting all the elements that have the max value while chaining methods (namely, without having a handle on the sorted array)

Suppose that you need to get all the elements that have the max value in an array.

A possible method would be to sort the array then use Enumerable#take_while:

array = [ 1, 3, 2, 3, 2, 3 ].sort {|a,b| b - a}
array.take_while { |e| e == array[0] }
#=> [3, 3, 3]

Now, when you are beautifully chaining methods and don't want to stop the chain just for storing the sorted array (which you'll need for referencing its first element in the take_while block), how would you do it?
I posted the question and an answer below for reference, but I probably missed better ways, so feel free to post your own method

Upvotes: 0

Views: 145

Answers (3)

Cary Swoveland
Cary Swoveland

Reputation: 110725

Another way:

arr = [ 1, 3, 2, 3, 2, 3 ]
arr.sort {|a,b| b - a}.tap { |a| a.select! { |e| e == a.first } }
  #=> [3, 3, 3]

Note that arr is not mutated.

Upvotes: 2

Fravadona
Fravadona

Reputation: 17198

ruby < 2.5
  • My original response to the question: sort.slice_when.first
[ 1, 3, 2, 3, 2, 3 ].sort {|a,b| b - a}.slice_when {|a,b| b != a}.first
#=> [3, 3, 3]

note: As slice_when returns an Enumerator, this solution won't walk through all the sorted array when chaining it with first. There is a more performant solution below tough.


ruby >= 2.5
  • Combining @engineersmnky and @Cary methods: then and max+select
[ 1, 3, 2, 3, 2, 3 ].then { |arr| mx = arr.max; arr.select { |elm| elm == mx } }
#=> [3, 3, 3]

Upvotes: 1

Sadman Ahmed
Sadman Ahmed

Reputation: 161

You can try this

pry(main)> [ 1, 2, 2, 3, 3, 3 ].sort.slice_when {|a,b| b > a}.to_a.last 
=> [3, 3, 3]

A bit similar of the last solution but also different.

Source https://ruby-doc.org/core-3.0.2/Enumerable.html#method-i-slice_when

Upvotes: 0

Related Questions