I have an array of instances of model Foo
. Foo
is an Ohm based data store. Each instance of Foo
has an_id
and integer attributes such as follows
, likes
. If there are two instances of Foo
with the same an_id
, I'd love to add the follows
and likes
attributes together. The solution I had was to create a hash where each key is an an_id
of the array, and keep the state there. If the array is large enough, this is not efficient as I need each object back into an array. I'd love to group the array by Foo#an_id
and merge/add the counter attributes together and pop that back into the array. Is something like this currently supported?
Asked
Active
Viewed 2,627 times
0

sawa
- 165,429
- 45
- 277
- 381

randombits
- 47,058
- 76
- 251
- 433
2 Answers
1
As a start, something like this:
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
Example output: sums_by_id => {1 => {:follows => 2, :likes => 4}, 2 => ...
Additionally, take a look at:
(5..10).inject {|sum, n| sum + n } # 45

Matt Dressel
- 2,194
- 16
- 18
-
I think the problem with the solution above is I need this back into an array so I can perform a sort operation. Ideally I'd like to sort by follows/likes etc. Is there a trivial way to do so using the data structure you built above? – randombits Feb 25 '13 at 04:32
-
sums_by_id.to_a.sort_by {| obj | block } → array – Matt Dressel Feb 25 '13 at 04:45
-
You might want to consider doing this in the database. Model.where(:some_id_attr => an_id).all.order('follows DESC'), or use active record :group and :sum – Matt Dressel Feb 25 '13 at 04:58
0
You can use inject
to get a sum of values:
array = *array of Foo*
total = array.inject { |sum, x| sum + x.likes }

Richard Brown
- 11,346
- 4
- 32
- 43