按多个值进行 Ruby 排序?

我有一个散列数组:

a=[{ 'foo'=>0,'bar'=>1 },
{ 'foo'=>0,'bar'=>2 },
... ]

我希望首先按照每个散列的‘ foo’对数组排序,然后按照‘ bar’对数组排序。谷歌告诉我它是这样做的:

a.sort_by {|h| [ h['foo'],h['bar'] ]}

但是这给了我 ArgumentError“ Array 与 Array 的比较失败”。这是什么意思?

47606 次浏览
a.sort { |a, b| [a['foo'], a['bar']] <=> [b['foo'], b['bar']] }

What you have posted works in Ruby 1.8.7:

ruby-1.8.7-p302 > a = [{'foo'=>99,'bar'=>1},{'foo'=>0,'bar'=>2}]
=> [{"foo"=>99, "bar"=>1}, {"foo"=>0, "bar"=>2}]


ruby-1.8.7-p302 > a.sort_by{ |h| [h['foo'],h['bar']] }
=> [{"foo"=>0, "bar"=>2}, {"foo"=>99, "bar"=>1}]


ruby-1.8.7-p302 > a.sort_by{ |h| [h['bar'],h['foo']] }
=> [{"foo"=>99, "bar"=>1}, {"foo"=>0, "bar"=>2}]

It probably means you're missing one of the fields 'foo' or 'bar' in one of your objects.

The comparison is coming down to something like nil <=> 2, which returns nil (instead of -1, 0 or 1) and #sort_by doesn't know how to handle nil.

Try this:

a.sort_by {|h| [ h['foo'].to_i, h['bar'].to_i ]}

This error appeares when you have unstable keys and trying to sort by them. Example:

[{'foo'=>99,'bar'=>1},{'foo'=>0,'bar'=>2, 'qwe' => 7}]
a.sort_by{|v| v['qwe']}
ArgumentError: comparison of NilClass with 7 failed

Try to do

a.sort_by{|v| [v['qwe']].select{|k| not k.nil?}}

But it doesnt work for me in

[v['index'],v['count'],v['digit'],v['value']]

where digit is unstable

This exception occurs when the result array used for the comparison contains both nil and non-nil values.

comparison of Array with Array failed

This means (at least in my case) that the types of array elements are different. When I made sure all array items are of the same time (Integer, for example), sorting started to work.

consider compacting the array (removing nil entries), and as a bonus, if it's string comparision, downcase the values for case insensitive sorting.

a.compact.sort_by { |h| [h['foo'].downcase, h['bar'].downcase] }

I was working on a task where I needed to sort array of hashes by different keys and different directions (by first key ascending, by second descending and etc.)

I've created this helper class, called it AwesomeSort because it's awesome and it's written in Ruby.

https://gist.github.com/pucinsk/36ffef881622b2d9dcca6716f403dc27