3

I have an array similar to this:

a = [
  [0, {:a=>"31", :b=>"21"}],
  [1, {:a=>"32", :b=>"11"}],
  [1, {:a=>"25", :b=>"19"}],
  [0, {:a=>"12", :b=>"10"}]
]

And I want to sort it by the first element of each row or by the various elements of the hash (2nd element in the row).

0

3 Answers 3

7

to sort by the first item in the Array:

> a.sort_by{|x| x.first}
 => [[0, {:a=>"31", :b=>"21"}], 
     [0, {:a=>"12", :b=>"10"}], 
     [1, {:a=>"32", :b=>"11"}], 
     [1, {:a=>"25", :b=>"19"}]] 

to sort by the first item in the Hash:

> a.sort_by{|x| x.last.first}
 => [[0, {:a=>"12", :b=>"10"}],
     [1, {:a=>"25", :b=>"19"}], 
     [0, {:a=>"31", :b=>"21"}], 
     [1, {:a=>"32", :b=>"11"}]] 

or you could sort by a given key of the hash:

> sort_key = :b
> a.sort_by{|x| x.last[ sort_key ]}
 => [[0, {:a=>"12", :b=>"10"}],
     [1, {:a=>"32", :b=>"11"}],
     [1, {:a=>"25", :b=>"19"}],
     [0, {:a=>"31", :b=>"21"}]] 

If you want to sort by the first array value, and then by the first entry in the hash, as a secondary search criteria, the answer is:

> a.sort_by{|x| [x.first, x.last.first]}
 => [[0, {:a=>"12", :b=>"10"}], 
     [0, {:a=>"31", :b=>"21"}], 
     [1, {:a=>"25", :b=>"19"}], 
     [1, {:a=>"32", :b=>"11"}]] 
Sign up to request clarification or add additional context in comments.

2 Comments

Note that "first entry in the hash" only works in Ruby 1.9. Hashes in ruby 1.8 only have keys, and no implicit order.
By "or" I meant to ways of sorting it: 1) by the first element of each row 2) by the first element in the hash (which itself is the second element in the row) P.S. I just added a comment with my solution. It works, but I'm wondering if there's a better way.
1
a = [
  [0, {:a=>"31", :b=>"21"}],
  [1, {:a=>"32", :b=>"11"}],
  [1, {:a=>"25", :b=>"19"}],
  [0, {:a=>"12", :b=>"10"}]
]
p a.sort_by{|el| [el.first, *el.last.values]}

Output:

=> [[0, {:a=>"12", :b=>"10"}], 
    [0, {:a=>"31", :b=>"21"}], 
    [1, {:a=>"25", :b=>"19"}], 
    [1, {:a=>"32", :b=>"11"}]]

4 Comments

this doesn't seem to be sorted at all
@UnixGuy How is it not sorted? It looks right to me: ordered by the first element, followed by the elements in the hash.
@Unix guy : it's sorted by the first element of the arays (so 0 comes before 1); if those are the same the value of key :a of the hash decides who comes first, then the value of key :b. (Added output to the answer).
sorry, my bad! I'll take that back. @steenslag posted "a" instead of posting the result, that was confusing ... +1 for his solution! I also fixed his output formatting
0

Well, I found an answer to my own question. Please compare & comment.

#sort by first item of each row (number)
a.sort{|x,y| x[0] <=> y[0]}

#sort by the first item in the hash
a.sort{|x,y| x[1][:a] <=> y[1][:a]}

Comments

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.