2011-01-07 5 views
1

Есть ли более удобный (и эквивалентный) способ сортировки таких элементов?Ruby: Есть ли лучший способ написать следующий метод сортировки?

items.sort! do |p1, p2| 
    if (p1.foo == p2.foo) 
    if (p1.bar == p2.bar) 
     if (p1.moo == p2.moo) 
     p1.wow <=> p2.wow    # Ascending order 
     else 
     p2.sam.moo <=> p1.sam.moo  # Descending order, 2 levels attribute 
     end 
    else 
     p2.bar <=> p1.bar     # Descending order 
    end 
    else 
    p1.foo <=> p2.foo     # Ascending order 
    end 
end 

ответ

3

Вы можете включить объекты в массивах для сравнения

[p1.foo, p1.bar, p1.moo, p1.sam.moo] <=> [p2.foo, p2.bar, p2.moo, p2.sam.moo] 

Массивы сравниваются так же, как строки: первым отличающегося элемента.

Если инверсные индексы в некоторых сравнениях (p2.bar <=> p1.bar) не являются опечатками, вам также нужно будет переключать элементы массива.

Или вы можете переопределить оператор сравнения в классе

def <=>(p2) 
    ... 
    end 

В этом случае вам не нужно будет передать что-нибудь в items.sort!.

+0

Это действительно хорошо! Большое спасибо! –

+1

Для немного меньшего дублирования вы можете написать 'items.sort_by! {| p | [p.foo, p.bar, p.moo, p.sam.moo]} 'если они все в порядке возрастания. –

+1

@Ben Alpert: а если нет, но это цифры, вы можете сделать sort_by! {| p | [p.foo, - p.bar, - p.moo]} ' –

Смежные вопросы