Сортировать объекты по логическим значениям в Ruby - PullRequest
3 голосов
/ 24 мая 2009

Приношу свои извинения, если на этот вопрос уже был дан ответ или он очевиден ... Я провел поиск здесь и в Goog и не смог найти ответ.

Я хочу отсортировать массив провайдеров по цене, и являются ли они предпочтительным провайдером? (истина или ложь)

Например, в array p of Providers ...

p1.price == 1, p1.preferred_provider? == false
p2.price == 2, p2.preferred_provider? == true
p2.price == 3, p3.preferred_provider? == true

Я бы хотел p.sort_by и получить:

[p2 p3 p1]

IAW

p.sort_by {|x| x.preferred_provider?, x.price }

не работает и получает ...

undefined method `<=>' for false:FalseClass

Какие-нибудь предложения о лучших способах решения этой проблемы?

Ответы [ 2 ]

8 голосов
/ 24 мая 2009

Большинство языков предоставляют функции сортировки, которые принимают компараторы для такого рода вещей. В Ruby это просто array.sort:

p.sort {|a, b| if (a.preferred_provider? == b.preferred_provider?
               then a.price <=> b.price
               elsif a.preferred_provider?
                    1
               else -1
       }
3 голосов
/ 24 мая 2009

Вы можете определить <=> в классе Provider, чтобы делать то, что вы хотите, а затем отсортировать, используя метод Array.sort (вместо Enumerable.sort_by). Вот определение <=>, которое я набрал:

class Provider
  def <=>(other)
    if preferred_provider?
      if other.preferred_provider?
        @price <=> other.price
      else
        1
      end
    else
      if other.preferred_provider?
        -1
      else
        @price <=> other.price
      end
    end
  end
end

Тогда, если у вас есть массив p, вы можете просто сделать p_sorted = p.sort.

(Обратите внимание, что я не тестировал этот код, поэтому может быть несколько ошибок, но я думаю, что он служит для демонстрации идеи.)

...