2013-02-25 2 views
0

У меня есть массив экземпляров модели Foo. Foo - это хранилище данных на основе Ohm. Каждый экземпляр Foo имеет an_id и целочисленные атрибуты, такие как follows, likes. Если есть два экземпляра Foo с тем же an_id, я бы хотел добавить вместе атрибуты и likes. Решение, которое у меня было, заключалось в создании хэша, где каждый ключ представляет собой массив an_id, и сохраняйте его там. Если массив достаточно велик, это неэффективно, так как мне нужен каждый объект обратно в массив. Мне бы хотелось сгруппировать массив по Foo#an_id и объединить/добавить атрибуты счетчика вместе и поместить их обратно в массив. Что-то вроде этого в настоящее время поддерживается?Эффективный способ группировки этого рубинового массива объектов

ответ

1

group_by, sum

В начале, что-то вроде этого:

grouped_hash = your_array.group_by(&:an_id) 
sums_by_id = {} 
grouped_hash.each do |id,values| 
    sums_by_id[id] = {} 
    # you could also just iterate over values once and += :follows and :likes 
    sums_by_id[id][:follows] = values.sum(&:follows) 
    sums_by_id[id][:likes] = values.sum(&:likes) 
end 

Пример вывода: sums_by_id => {1 => {: следует => 2,: любит => 4} , 2 => ...

Кроме того, обратите внимание на:

inject

(5..10).inject {|sum, n| sum + n } # 45 
+0

Я думаю, что проблема с решением выше, мне это нужно обратно в массив, чтобы я мог выполнить операцию сортировки. В идеале я хотел бы сортировать по следующим/любимым и т. Д. Существует ли тривиальный способ сделать это с использованием структуры данных, которую вы создали выше? – randombits

+0

sums_by_id.to_a.sort_by {| obj | block} → array –

+0

Возможно, вы захотите сделать это в базе данных. Model.where (: some_id_attr => an_id) .all.order ('следует DESC') или использует активную запись: group и: sum –

0

Вы можете использовать inject, чтобы получить сумму значений:

array = *array of Foo* 
total = array.inject { |sum, x| sum + x.likes } 

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

  • Нет связанных вопросов^_^