Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails Ruby array of hashes merged by key to average value

I have an activerecord method that finds all events for the week, myevents.map { |x| x.start_date.day => [x.title]} (start_date is a datetime field, title is a string) which gives me an array of hashes;

    [{11=>["40"]}, {11=>["0"]}, {11=>["0"]}, {11=>[""]}, 
     {11=>["0"]}, {11=>["0"]}, {11=>["33"]}, {12=>["9"]}, 
     {11=>["34"]}, {11=>["29"]}, {11=>["8"]}, {11=>["31"]}, 
     {11=>["40"]}, {11=>["34"]}] 

I want to map the values so I get an array that looks like;

[ {11=>[ average of values that occur on the 11th]}, 
  {12=>[average of values that occur on the 12th]} ]

but I'm not quite sure how to get it.

like image 840
raphael_turtle Avatar asked Mar 20 '23 06:03

raphael_turtle


1 Answers

I'd do using group_by , inject and map .

ar = [  
        {11=>["40"]}, {11=>["0"]}, {11=>["0"]}, {11=>[""]},
        {11=>["0"]}, {11=>["0"]}, {11=>["33"]}, {12=>["9"]},
        {11=>["34"]}, {11=>["29"]}, {11=>["8"]}, {11=>["31"]}, 
        {11=>["40"]}, {11=>["34"]}
     ]

# first grouping the inner hash keys like on 11,12,etc. In each iteration, 
# {11=>["40"]}, {11=>["0"]} are being passed to the block of `group_by`. Now
# `h.keys.first` gives 11 from `{11=>["40"]}` and 11 from `{11=>["0"]}` likewise.
ary = ar.group_by { |h| h.keys.first }.map do |k,v|
  { k => v.map { |h| h[k][0].to_i }.inject(:+) / v.size } 
end

ary # => [{11=>19}, {12=>9}]
like image 181
Arup Rakshit Avatar answered Apr 02 '23 21:04

Arup Rakshit