Skip to content

Instantly share code, notes, and snippets.

@robjlucas
Last active June 4, 2019 12:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robjlucas/8d454abf161033ff9d01616b27c65d1e to your computer and use it in GitHub Desktop.
Save robjlucas/8d454abf161033ff9d01616b27c65d1e to your computer and use it in GitHub Desktop.
How to transform this array of hashes more elegantly?
array = [{"no_in_series"=>116, "recipient_type"=>"individual", "subscriptions"=>3971},
{"no_in_series"=>116, "recipient_type"=>"institution", "subscriptions"=>838},
{"no_in_series"=>116, "recipient_type"=>"student", "subscriptions"=>509},
{"no_in_series"=>115, "recipient_type"=>"individual", "subscriptions"=>3859},
{"no_in_series"=>115, "recipient_type"=>"institution", "subscriptions"=>805},
{"no_in_series"=>115, "recipient_type"=>"student", "subscriptions"=>441}]
array.group_by {|r| r["no_in_series"]}
.map {|k,v| {k => v.map {|r| {r["recipient_type"] => r["subscriptions"]}}}}
.map {|h| {h.keys.first => h.values.first.inject(&:merge)}}
# => [{116=>{"individual"=>3971, "institution"=>838, "student"=>509}}, {115=>{"individual"=>3859, "institution"=>805, "student"=>441}}]
@baweaver
Copy link

baweaver commented Jun 3, 2019

array.each_with_object(Hash.new { |h, k| h[k] = Hash.new(0) }) do |item, counts|
  number, recipient, count = item.values_at('no_in_series', 'recipient_type', 'subscriptions')
  counts[number][recipient] += count
end
=> {116=>{"individual"=>3971, "institution"=>838, "student"=>509},
 115=>{"individual"=>3859, "institution"=>805, "student"=>441}}

@havenwood
Copy link

array.group_by do |h|
  h['no_in_series']
end.transform_values do |value|
  value.to_h do |h|
    [h['recipient_type'], h['subscriptions']]
  end
end

@robjlucas
Copy link
Author

Excellent! Thanks very much both. My brain was in meltdown yesterday while trying to figure this out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment