Ruby按多个值排序?

时间:2010-11-30 01:18:38

标签: ruby

我有一系列哈希:

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

我想先按每个哈希的'foo'排序数组,然后按'bar'排序。谷歌告诉我这就是它的完成方式:

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

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

7 个答案:

答案 0 :(得分:64)

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

答案 1 :(得分:18)

这可能意味着您错过了其中一个对象中的某个字段'foo'或'bar'。

比较结果类似nil <=> 2,返回nil(而不是-101)和{{1} }不知道如何处理#sort_by

试试这个:

nil

答案 2 :(得分:12)

您发布的内容适用于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}] 

答案 3 :(得分:3)

当用于比较的结果数组包含nil和non-nil值时,会发生此异常。

答案 4 :(得分:0)

如果您有不稳定的密钥并尝试按它们排序,则会出现此错误。 例如:

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

尝试

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

但它在

中对我不起作用
[v['index'],v['count'],v['digit'],v['value']]

数字不稳定

答案 5 :(得分:0)

  

将数组与数组比较失败

(至少就我而言)这意味着数组元素的类型不同。当我确定所有数组项都在同一时间(例如SELECT CASE WHEN rn1 = 1 THEN name1 END AS name1 , CASE WHEN rn2 = 1 THEN name2 END AS name2 , CASE WHEN rn3 = 1 THEN name3 END AS name3 , CASE WHEN rn4 = 1 THEN name4 END AS name4 FROM ( SELECT t1.name::text AS name1, t2.name::text AS name2, t3.name::text AS name3, t4.name::text AS name4 , row_number() OVER (PARTITION BY t1.id ORDER ORDER BY t2.id, t3.id, t4.id) AS rn1 , row_number() OVER (PARTITION BY t1.id, t2.id ORDER ORDER BY t3.id, t4.id) AS rn2 , row_number() OVER (PARTITION BY t1.id, t2.id, t3.id ORDER ORDER BY t4.id) AS rn3 FROM t1 LEFT JOIN t2 b ON t2.t1_id = t1.id LEFT JOIN t3 c ON t3.t2_id = t2.id LEFT JOIN t4 d ON t4.t3_id = t3.id WHERE t1.id = 'a1' ) sub ORDER BY t1.id, t2.id, t3.id, t4.id; )时,排序就开始起作用了。

答案 6 :(得分:0)

考虑压缩数组(除去nil个条目),此外,如果是字符串比较,则将值小写以区分大小写。

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