Как бы мне передать критерии сортировки в метод, чтобы его можно было использовать sort_by

#ruby-on-rails #ruby

#ruby-on-rails #ruby

Вопрос:

Как бы мне передать имя атрибута методу sort_by и использовать его внутри? Например, допустим, я хотел создать FrequencyCounter с массивом одноэлементных объектов Foo . (Важно, чтобы они были одиночными, потому что это означает, что будет определенное количество идентичных Foo ов).

 class Foo
  attr_accessor :arbitrary_sorter
  def initialize arbitrary_sorter
    @arbitrary_sorter = arbitrary_sorter
  end
end

class FrequencyCounter
  def initialize ary
    #multiset will create a hash of frequency like {3=>obj, 2->obj, 2=>obj, etc}
    @hash = Multiset.new(ary).hash
  end

  def sort_by params={}
    Hash[@hash.sort_by {|k,v| [-1 * v, -1 * k]}]
  end
end
  

И когда я создаю объект Frequency:

 @fc = FrequencyCounter.new([Foo.get(5), Foo.get(4), Foo.get(5), Foo.get(1)])
  

Я хотел бы рассказать, @fc что заказывать на:

 @fc.sort_by(:arbitrary_sorter)
  

Возможно ли это?

Комментарии:

1. Что такое Foo.get ? Он не определен.

2. Это просто способ извлечения синглтона с заданным значением arbitrary_sorter

Ответ №1:

в любом перечислителе вы можете указать ему, по чему сортировать. Итак, давайте рассмотрим простой пример:

 class Animal
  attr_accessor :name, :leg_count
  def initialize(name, leg_count)
    @name = name
    @leg_count = leg_count
  end
  def to_s
    @name
  end
end

animals = [Animal.new('human', 2), Animal.new('dog', 4), Animal.new('snake', 0)]
 => [human, dog, snake] 

# sort by an attribute or method on the model
animals.sort_by{|a| a.leg_count} 
 => [snake, human, dog] 
  

То же, что:

 animals.sort_by(amp;:leg_count)
 => [snake, human, dog]
  

Вы можете даже сделать что-то вроде:

 sorter_lambda = lambda {|animal| animal.name == "human" ? 0 : 999}
animals.sort_by(amp;sorter_lambda)
 => [human, dog, snake] 
  

Лямбда-выражение может лучше всего подходить для вас со сложной логикой, которую я видел.