Ruby sort by multiple values?

后端 未结 7 918
南旧
南旧 2020-12-07 22:05

I have an array of hashes:

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

I want to sort the array first

相关标签:
7条回答
  • 2020-12-07 22:14

    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 ]}
    
    0 讨论(0)
  • 2020-12-07 22:14

    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

    0 讨论(0)
  • 2020-12-07 22:27

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

    0 讨论(0)
  • 2020-12-07 22:29

    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] }
    
    0 讨论(0)
  • 2020-12-07 22:31

    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.

    0 讨论(0)
  • 2020-12-07 22:33

    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}] 
    
    0 讨论(0)
提交回复
热议问题