user2270029
user2270029

Reputation: 871

Ruby Merge List of Hashes & Get Average

I have the following list of hashes:

[{"day":3,"count":2},{"day":1,"count":2},{"day":1,"count":2},{"day":2,"count":2},{"day":1,"count":2},{"day":4,"count":2},{"day":5,"count":2},{"day":6,"count":2},{"day":4,"count":2},{"day":4,"count":2},{"day":3,"count":2},{"day":3,"count":2},{"day":2,"count":2},{"day":6,"count":2},{"day":0,"count":2},{"day":5,"count":2},{"day":0,"count":2},{"day":5,"count":2},{"day":4,"count":2},{"day":1,"count":2},{"day":0,"count":2},{"day":0,"count":2},{"day":2,"count":2},{"day":2,"count":2},{"day":2,"count":2},{"day":1,"count":2},{"day":6,"count":2},{"day":5,"count":2},{"day":3,"count":2},{"day":2,"count":2},{"day":2,"count":2},{"day":1,"count":2},{"day":5,"count":2},{"day":4,"count":2},{"day":2,"count":2}]

I want to merge together all the keys that have the same "day" value and then get the mean average of the second key/value pair's average.

So for example, my final output should look like:

[{"day":0, "count": 2}, {"day":1, "count": 2}, {"day":3, "count": 2}, {"day":4, "count": 2}, {"day":5, "count": 2}, {"day":6, "count": 2}, {"day":7, "count": 2},]

The count average would actually be calculated (not always "2"), I was just using two as an example.

Upvotes: 2

Views: 597

Answers (2)

Amadan
Amadan

Reputation: 198314

# group the list into sublists sharing the same day
data.group_by { |element| element['day'] }.map { |day, element_list|
  # for each day, return a new object
  {
    day:   day,
    # extract the count from all the elements in the sublist,
    # then add them together and divide by number of elements
    # (convert to float to avoid integral division)
    count: element_list.map { |element| element['count'] }.
             reduce(:+).to_f / element_list.size
  }
}

Upvotes: 3

Carl Zulauf
Carl Zulauf

Reputation: 39558

This would work, assuming your collection of hashes is called data:

days = data.group_by{|record| record["day"] }
days.map do |day, records|
  {day: day, count: records.map{|record| record["count"] }.average}
end

Upvotes: 2

Related Questions