#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]
Лямбда-выражение может лучше всего подходить для вас со сложной логикой, которую я видел.