2009-05-19 21 views

Odpowiedz

31

Tak, używając Array#sort! jest to łatwe.

myarray.sort! { |a, b| a.attribute <=> b.attribute } 
+0

Thnx kumpel ale mi się nie udało Mam tablicę obiektów. W którym utworzono jeden z atrybutów obiektu. Chcę posortować to za pomocą tego pola. więc zrobiłem @ comm_bytes.sort! {| a, b | a.created_at <=> b.created_at} ale bez powodzenia dla mnie możesz pomóc .... ?? –

+3

Czy istnieje metoda created_at mająca dostęp do atrybutu @created_at? Jakiego rodzaju obiektem jest @created_at? Czy definiuje '<=>'? Jakie błędy dostaniesz? itd., itp., ad nauseum. Innymi słowy, potrzebujemy więcej szczegółów niż "ale bez powodzenia dla mnie". – rampion

+0

działa, jeśli zrobisz myarray = myarray.sort {...} bez "!" – DoruChidean

8

Array # sort działa dobrze, jak pisał powyżej:

myarray.sort! { |a, b| a.attribute <=> b.attribute } 

ALE, trzeba upewnić się, że operator <=> jest realizowany dla tego atrybutu. Jeśli jest to rodzimy typ danych Ruby, nie stanowi to problemu. W przeciwnym razie napisz własną implementację, która zwraca -1, jeśli < b, 0, jeśli są równe, i 1, jeśli a> b.

146

polecam korzystania sort_by zamiast:

objects.sort_by {|obj| obj.attribute} 

Zwłaszcza jeśli atrybut może być obliczona.

+65

Lub skrócona wersja: 'objects.sort_by (&: atrybut)' – Nikola

+3

jeszcze bardziej krótszy objects.sort_by &: atrybut –

+1

Jeśli masz problemy z pisownymi dużymi i małymi literami, możesz użyć 'objects.sort_by {| obj | obj.attribute.downcase} ' – campeterson

14

w przypadku trzeba sortowania przez dwóch atrybutów, gdzie pierwsza jest ważniejsze następnie drugi (środki, przy uwzględnieniu drugiego argumenty tylko jeśli pierwsze argumenty są równe), to może to zrobić jak ten

myarray.sort{ |a,b| (a.attr1 == b.attr1) ? a.attr2 <=> b.attr2 : a.attr1 <=> b.attr1 } 

lub w przypadku tablicy tablic

myarray.sort{ |a,b| (a[0] == b[0]) ? a[1] <=> b[1] : a[0] <=> b[0] } 
+0

Hmmm DZIĘKUJĘ! – MrYoshiji

10

można wprowadzić dowolny klasa sortable poprzez nadpisanie < => metoda:

class Person 

    attr_accessor :first_name, :last_name 

    def initialize(first_name, last_name) 
    @first_name = first_name 
    @last_name = last_name 
    end 

    def <=>(per) 
    @last_name + @first_name <=> per.last_name + per.first_name 
    end 

end 

Teraz tablica obiektów Person będzie sortowalna na last_name.

ar = [Person.new("Eric", "Cunningham"), Person.new("Homer", "Allen")] 

puts ar # => [ "Eric Cunningham", "Homer Allen"] (Person objects!) 

ar.sort! 

puts ar # => [ "Homer Allen", "Eric Cunningham" ] 
-1
@model_name.sort! { |a,b| a.attribute <=> b.attribute } 
+2

Istnieje wiele identycznych odpowiedzi opublikowanych w 2009 roku. Nie ma potrzeby dodawania kolejnego. – interjay

+2

Nie należy używać sortowania podczas sortowania obiektów, których nie można bezpośrednio porównać. Jeśli musisz uzyskać dostęp do atrybutów lub wykonać obliczenia, aby uzyskać wartość do porównania, użyj "sort_by". Będzie znacznie szybciej. –

13

porządku rosnącym:

objects_array.sort! { |a, b| a.attribute <=> b.attribute } 

lub

objects_array.sort_by{ |obj| obj.attribute } 

porządku malejącym:

objects_array.sort! { |a, b| b.attribute <=> a.attribute } 

lub

objects_array.sort_by{ |obj| obj.attribute }.reverse 
5

bardziej elegancki objects.sort_by(&:attribute) można dodać oon w .reverse jeśli trzeba zmienić kolejność.

Powiązane problemy