2012-02-05 11 views
18

Por lo tanto, hemos construido una matriz personalizada de los usuarios, como por ejemplo:usando sort_by en ruby ​​(para rieles)?

[["user1",432],["user1",53],["user9",58],["user5",75],["user3",62]] 

Quiero ordenarlos por el valor 2n'd en cada matriz, de mayor a menor. Tengo la sensación de usar una especie o sort_by para las matrices es la manera de hacer esto, pero no estoy muy seguro de cómo lograrlo

Respuesta

39

sort_by

Si está interesado en sort_by, podría desestructurar las matrices internas

array.sort_by { |_, x| x }.reverse 

o llamar al operador de índice de

array.sort_by { |x| x[1] }.reverse 

En lugar de invertir, puede negar los valores devueltos desde el bloque.

array.sort_by { |_, x| -x } 
array.sort_by { |x| -x[1] } 

Otra alternativa sería utilizar un ampersand y Array#last.

array.sort_by(&:last).reverse 

tipo

Una solución podría ser el uso de sort

array.sort { |x, y| y[1] <=> x[1] } 
+0

+1 para diferentes soluciones :) –

+3

Si va a completar, puede incluir 'array.sort_by (&: last) .reverse'. –

+1

y para completar, debe agregar el simple 'array.sort_by {| u, uid | -uid} '. Además, tenga en cuenta que podría beneficiarse al usar 'Enumerable # reverse_each' para una reversión más eficiente desde el punto de vista del espacio (cuando un enumerador se ajusta, por supuesto). – tokland

2

uso esto: array.sort_by { |a| -a[1] }

+0

Siempre he sido un enigma por 'sort_by' que no tiene una opción inversa. – tokland

+0

nit-picking: desempaquetar los argumentos del bloque se considera más idiomático que acceder a ellos como una matriz. – tokland

0

Una solución a más sort_by a la inversa (- no funciona en todos los casos, piense clasificación por cadena):

class Invertible 
    include Comparable 
    attr_reader :x 

    def initialize(x) 
    @x = x 
    end 

    def <=> (x) 
    x.x <=> @x 
    end 
end 

class Object 
    def invertible 
    Invertible.new(self) 
    end 
end 

[1, 2, 3].sort_by(&:invertible) #=> [3, 2, 1] 
["a", "b", "c"].sort_by(&:invertible) #=> ["c", "b", "a"] 

Es más lento que invertir en simple ca se, pero puede funcionar mejor con géneros complejos:

objs.sort_by do |obj| 
    [obj.name, obj.date.invertible, obj.score, ...] 
end 
Cuestiones relacionadas