Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use sort_by with values that could be nil? [duplicate]

Let's say I have an array of: [{one: 1, two: 2}, {one: 5, two: 6}] and I want to use sort_by something like:

[1] pry(main)> [{one: 1, two: 2}, {one: 5, two: 6}].sort_by{|x| [x[:one], x[:two]]}

However when I introduce nil for one of the values I get ArgumentError: comparison of Array with Array failed :

=> [{:one=>1, :two=>2}, {:one=>5, :two=>6}]
[2] pry(main)> [{one: 1, two: 2}, {one: nil, two: 6}].sort_by{|x| [x[:one], x[:two]]}
ArgumentError: comparison of Array with Array failed

How can I avoid this error?

like image 233
Eki Eqbal Avatar asked Feb 21 '16 16:02

Eki Eqbal


1 Answers

Use this syntax,

starred.sort_by { |a| [a ? 1 : 0, a] }

When it has to compare two elements, it compares an arrays. When Ruby compares arrays (calls === method), it compares 1st element, and goes to the 2nd elements only if the 1st are equal. ? 1 : 0 guarantees, that we'll have Fixnum as 1st element, so it should be no error.

If you do ? 0 : 1, nil will appear at the end of array instead of beginning. Here is an example:

irb> [2, 5, 1, nil, 7, 3, nil, nil, 4, 6].sort_by { |i| [i ? 1 : 0, i] }
=> [nil, nil, nil, 1, 2, 3, 4, 5, 6, 7]

Source.

like image 189
Albert Paul Avatar answered Oct 14 '22 16:10

Albert Paul