2

I want to sort this array by two different conditionals.

First I want to sort the array by type: A type can be either (1,2,3,4) and I want to sort them in this order 4 - 1 - 2 - 3.

Then within each different type I want to sort them by a percentage descending.

So a sorted array would look like this:

[
  <OpenStruct percent=70, type=4>,
  <OpenStruct percent=60, type=4>,
  <OpenStruct percent=50, type=4>,
  <OpenStruct percent=73, type=1>,
  <OpenStruct percent=64, type=1>,
  <OpenStruct percent=74, type=2>
]ect

How can I accomplish this sort? Currently I can only sort by type descending.

array = array.sort_by {|r| r.type }
Jay
  • 928
  • 2
  • 7
  • 28

1 Answers1

3

This should do it:

require 'ostruct'
arr = [
  OpenStruct.new(percent: 73, type: 1),
  OpenStruct.new(percent: 70, type: 4),
  OpenStruct.new(percent: 60, type: 4),
  OpenStruct.new(percent: 50, type: 4),
  OpenStruct.new(percent: 64, type: 1),
  OpenStruct.new(percent: 74, type: 2)
]


puts arr.sort_by { |a| [a.type % 4, -a.percent] }

output:

#<OpenStruct percent=70, type=4>
#<OpenStruct percent=60, type=4>
#<OpenStruct percent=50, type=4>
#<OpenStruct percent=73, type=1>
#<OpenStruct percent=64, type=1>
#<OpenStruct percent=74, type=2>
Anthony
  • 15,435
  • 4
  • 39
  • 69
  • 1
    Don't use `sort` for this. It will be much slower than an implementation using `sort_by`. See http://stackoverflow.com/a/2651028/128421 and compare the equivalent `sort` and `sort_by` tests. – the Tin Man Apr 24 '15 at 20:10