theartofbeing theartofbeing - 6 months ago 17
Ruby Question

Passing sort_by an array of sort fields

If I have a array of hashes

collection = [
{ first_name: 'john', last_name: 'smith', middle: 'c'},
{ first_name: 'john', last_name: 'foo', middle: 'a'}
]


And an array of keys I want to sort by:

sort_keys = ['first_name', 'last_name']


How can I pass these keys to
sort_by
given that the keys will always match the keys in the collection?

I've tried

collection.sort_by { |v| sort_keys.map(&:v) }


but this doesn't work. I believe I'll need to use a proc but I'm not sure how to implement it. Would appreciate any help!

Using Ruby 2.2.1

Answer

If you change your sort_keys to contain symbols:

sort_keys = [:first_name, :last_name]

You can use values_at to retrieve the values:

collection.sort_by { |h| h.values_at(*sort_keys) }
#=> [{:first_name=>"john", :last_name=>"foo", :middle=>"a"}, {:first_name=>"john", :last_name=>"smith", :middle=>"c"}]

The array that is used to sort the hashes looks like this:

collection.map { |h| h.values_at(*sort_keys) }
#=> [["john", "smith"], ["john", "foo"]]