У меня есть массив экземпляров модели Foo
. Foo
- это хранилище данных на основе Ohm. Каждый экземпляр Foo
имеет an_id
и целочисленные атрибуты, такие как follows
, likes
. Если есть два экземпляра Foo
с тем же an_id
, я бы хотел добавить вместе атрибуты и likes
. Решение, которое у меня было, заключалось в создании хэша, где каждый ключ представляет собой массив an_id
, и сохраняйте его там. Если массив достаточно велик, это неэффективно, так как мне нужен каждый объект обратно в массив. Мне бы хотелось сгруппировать массив по Foo#an_id
и объединить/добавить атрибуты счетчика вместе и поместить их обратно в массив. Что-то вроде этого в настоящее время поддерживается?Эффективный способ группировки этого рубинового массива объектов
0
A
ответ
1
В начале, что-то вроде этого:
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 => ...
Кроме того, обратите внимание на:
(5..10).inject {|sum, n| sum + n } # 45
0
Вы можете использовать inject
, чтобы получить сумму значений:
array = *array of Foo*
total = array.inject { |sum, x| sum + x.likes }
Я думаю, что проблема с решением выше, мне это нужно обратно в массив, чтобы я мог выполнить операцию сортировки. В идеале я хотел бы сортировать по следующим/любимым и т. Д. Существует ли тривиальный способ сделать это с использованием структуры данных, которую вы создали выше? – randombits
sums_by_id.to_a.sort_by {| obj | block} → array –
Возможно, вы захотите сделать это в базе данных. Model.where (: some_id_attr => an_id) .all.order ('следует DESC') или использует активную запись: group и: sum –