Abram
Abram

Reputation: 41884

Iterating over hash of arrays

I have the following:

@products = {
  2 => [
    #<Review id: 9, answer01: 3, score: 67, style_id: 2, consumer_id: 2,
    branch_id: 2, business_id: 2>
  ],
  15 => [
    #<Review id: 10, answer01: 3, score: 67, style_id: 2, consumer_id: 2,
    branch_id: 2, business_id: 2>,
    #<Review id: 11, answer01: 3, score: 67, style_id: 2, consumer_id: 2,
    branch_id: 2, business_id: 2>
  ]
}

I want to average the scores for all reviews associated with each product's hash key. How can I do this?

Upvotes: 2

Views: 7641

Answers (3)

Abram
Abram

Reputation: 41884

Thanks for the answer Shingetsu, I will certainly upvote it. I accidentally figured the answer out myself.

trimmed_hash = @products.sort.map{|k, v| [k, v.map{|a| a.score}]}
trimmed_hash.map{|k, v| [k, v.inject(:+).to_f/v.length]}

Upvotes: 1

Aaron Perley
Aaron Perley

Reputation: 629

Yes, just use map to make and array of the scores for each product and then take the average of the array.

average_scores = {}
@products.each_pair do |key, product|
  scores = product.map{ |p| p.score }
  sum = scores.inject(:+) # If you are using rails, you can also use scores.sum
  average = sum.to_f / scores.size
  average_scores[key] = average
end

Upvotes: 6

user1241335
user1241335

Reputation:

To iterate over a hash:

hash = {}
hash.each_pair do |key,value|
  #code
end

To iterate over an array:

arr=[]
arr.each do |x|
  #code
end

So iterating over a hash of arrays (let's say we're iterating over each array in each point in the hash) would be done like so:

hash = {}
hash.each_pair do |key,val|
  hash[key].each do |x|
    #your code, for example adding into count and total inside program scope
  end
end

Upvotes: 10

Related Questions