2010-11-30 21 views
53

que tienen un conjunto de valores hash:Ruby ordenar por valores múltiples?

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

Quiero ordenar la matriz por primera vez por cada una de hachís 'foo', y luego por 'bar'. Google me dice que esto es cómo se hace:

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

Pero esto me da la ArgumentError "comparación de matriz con arreglo defectuoso". ¿Qué significa esto?

+3

Funciona para mí. ¿Estás usando una versión anterior de ruby? –

+0

Estoy usando 1.8.7 – herpderp

+2

Lo que ha publicado funciona en 1.8.7. – Phrogz

Respuesta

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

Esto es lo mismo. 'Enumerable # sort_by (& block)' es aproximadamente 'sort {| a, b | block.call (a) <=> block.call (b)} ', excepto que se realiza de una manera más eficiente. Si esto funciona, pero 'sort_by' no, entonces algo más está mal. – wuputah

+0

Para llaves simples, la ordenación es más eficiente. Para claves complejas, sort_by es más eficiente. – dj2

+1

Hmm, ahora obtengo el mensaje "¡Tienes un objeto nulo cuando no lo esperabas!" error. La matriz exacta que utilicé es 'a = [{'foo' => 0, 'bar' => 2}, {'foo' => 0, 'bar' => 1}, {'foo' => 2, 'bar' => 1}, {'foo' => 1, 'bar' => 0}] '. – herpderp

12

obras Lo que has publicado en 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

¡Qué extraño! ¿Quién votaría esta respuesta? – Phrogz

14

probablemente significa que se está perdiendo uno de los campos de los foo "o 'bar' en una de sus objetos.

La comparación se viene abajo a algo así como nil <=> 2, que devuelve nil (en lugar de -1, 0 o 1) y #sort_by no sabe cómo manejar nil.

Prueba esto:

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

Este error appeares cuando se tiene teclas inestables y tratando de resolver por ellos. Ejemplo:

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

tratar de hacer

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

Pero no funciona para mí en

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

donde dígitos es inestable

+0

Ese no es el mismo error que informó el OP. –

1

Esta excepción se produce cuando la matriz utilizado Resultado para la comparación contiene valores nulos y no nulos.

Cuestiones relacionadas