2

How can I sort array of hashes if I have pre-determined order I have an array that needs to be sorted like this :

   array =  [{:attr_name=>:phone, :attr_value=>30}, {:attr_name=>:name, :attr_value=>20}, {:attr_name=>:similarity, :attr_value=>0}, {:attr_name=>:weight, :attr_value=>50}]

and I've got a hash based on which I want it to be sorted :

pre_sorted = {
            :name => 0,
            :phone => 1,
            :weight=> 2,
            :similarity => 3
        }

After sorting my array should look like this :

[{:attr_name=>:name, :attr_value=>20}, {:attr_name=>:phone, :attr_value=>30}, {:attr_name=>:weight, :attr_value=>50}, {:attr_name=>"similarity", :attr_value=>0}]

I've looked at the ruby sort and sort by docs and found related questions on So but couldn't figure it out because I'm just starting with rails.

2
  • Why is similarity a string in your array, but a symbol in the pre_sorted hash? Commented Jan 29, 2013 at 14:47
  • @sepp2k thanks that was a typo on my part, I've corrected it now Commented Jan 29, 2013 at 14:48

2 Answers 2

5

To sort an array by a given criterion, you can use sort_by. In your case you want to sort by the entry in the pre_sorted hash, so:

array.sort_by do |hash|
  pre_sorted[ hash[:attr_name] ]
end
Sign up to request clarification or add additional context in comments.

2 Comments

hi thanks for your answer, when I use your method I get the error comparison of Fixnum with nil failed
@GandalfStormCrow That happens if the block given to sort_by returns nil, which in this case would happen if pre_sorted did not contain a value for (at least) one of the attr_names. However given the code in the question, that should not (and in fact does not - I just tried it) occur.
1

Array#sort accepts a block of code to use for the comparison: http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-sort

array.sort{|a,b| pre_sorted[a[:attr_value]] <=> pre_sorted[b[:attr_value]]}

3 Comments

The second you start having to dive into an object or structure to access the values you want to compare, you should look at the cost required to get there, and think seriously about using sort_by. To understand why, read about the "Schwartzian transform", which is what sort_by uses. Randall Schwartz has a page discussing it for additional reading.
Huh. I wasn't aware there was an inherent optimization in sort_by. Ruby never fails to impress me.
It's not a Ruby optimization, it's a benefit of the transform.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.