红宝石来自类似哈希的元素总和

时间:2020-02-09 20:32:54

标签: ruby-on-rails ruby activerecord hash

假设我有以下记录,其中r_years可以具有任意数量的年份键:

Item.select('id','name','r_years').where(name:"N1")
...
"id" => 1, "name" => "N1", "r_years" => {"year2020" => "1","year2021" => "2", ...}
"id" => 2, "name" => "N1", "r_years" => {"year2020" => "2","year2021" => "3", ...}
...

每年如何获取r_years值的总和,就像这样:

@r_years_sum = {"year2020" => "3","year2021" => "5", ...}

3 个答案:

答案 0 :(得分:2)

您可以将结果映射为仅获取r_years值,然后使用reduce并合并每年的每个值并将它们的值作为整数求和:

items.map do |item|
  item['r_years']
end.reduce do |acc, item|
  item.merge(acc) { |_, oldval, newval| (oldval.to_i + newval.to_i).to_s }
end
# {"year2020"=>"3", "year2021"=>"5"}

答案 1 :(得分:1)

arr = [
  { "id"=>"1", "r_years"=>{ "2020"=>"1", "2021"=> "2", "2022"=>"3" } },
  { "id"=>"2", "r_years"=>{ "2020"=>"4", "2021"=> "5", "2022"=>"6" } },
  { "id"=>"3", "r_years"=>{ "2020"=>"7", "2021"=> "8", "2022"=>"9" } }
]

arr.each_with_object(Hash.new(0)) do |g,h|
  g["r_years"].each { |k,v| h[k] += v.to_i }
end.transform_values(&:to_s)
  #=> {"2020"=>"12", "2021"=>"15", "2022"=>"18"}

第一步是:

arr.each_with_object(Hash.new(0)) do |g,h|
  g["r_years"].each { |k,v| h[k] += v.to_i }
end
  #=> {"2020"=>12, "2021"=>15, "2022"=>18}
然后使用

Hash#transform_values将值转换为字符串。

这使用第二种形式的Hash::new,该形式采用称为默认值的参数。 h[c] += 1扩展为h[c] = h[c] + 1。如果h没有键c,则等式右边的h[c]返回默认值零,得出h[c] = 0 + 1

答案 2 :(得分:0)

您可以尝试...

arr = [
  { "id"=>"1", "r_years"=>{ "2020"=>"1", "2021"=> "2", "2022"=>"3" } },
  { "id"=>"2", "r_years"=>{ "2020"=>"4", "2021"=> "5", "2022"=>"6" } },
  { "id"=>"3", "r_years"=>{ "2020"=>"7", "2021"=> "8", "2022"=>"9" } }
]

res_hash=Hash.new(0)
arr.each do |x|
    x["r_years"].select{ |key,value| res_hash[key]+=value.to_i }
end