2012-02-05 14 views
18

Così ho costruito una gamma personalizzata di utenti, come ad esempio:usando sort_by in ruby ​​(per le guide)?

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

voglio ordinarli in base al valore 2n'd in ogni matrice, dal più grande al più piccolo. Ho la sensazione utilizzando sorta o sort_by per gli array è il modo per fare questo, ma io non sono davvero sicuro di come realizzarlo

risposta

39

sort_by

Se siete interessati in sort_by, si potrebbe destrutturare gli array interni

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

o chiamare l'operatore indice

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

Invece di invertire è possibile negare i valori restituiti dal blocco.

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

Ancora un'altra alternativa potrebbe essere quella di utilizzare un ampersand e Array#last.

array.sort_by(&:last).reverse 

sorta

Una soluzione che utilizza sort potrebbe essere

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

+1 per soluzioni diverse :) –

+3

Se si sta andando per completezza, si potrebbe voler includere 'array.sort_by (&: last) .reverse'. –

+1

e tuttavia per completezza dovresti aggiungere il semplice 'array.sort_by {| u, uid | -uid} '. Inoltre, si noti che potrebbe trarre beneficio dall'uso di 'Enumerable # reverse_each' per un'inversione di spazio più efficiente (quando un enumeratore si adatta, ovviamente). – tokland

2

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

+0

Sono sempre stato enigma per 'sort_by' non avendo un'opzione inversa. – tokland

+0

nit-picking: gli argomenti del blocco di disimballaggio sono considerati più idiomatici che accedervi come un array. – tokland

0

Un'altra soluzione per sort_by in senso inverso (- non funziona in tutti i casi, pensare l'ordinamento per stringa):

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"] 

È più lento del contrario in ca semplice se, ma può funzionare meglio con tipi complessi:

objs.sort_by do |obj| 
    [obj.name, obj.date.invertible, obj.score, ...] 
end 
Problemi correlati