You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对哈希数组按partner_id分组并求和value属性?

解决Ruby哈希数组按partner_id分组并累加value的问题

你的需求很明确——把给定的哈希数组按partner_id分组,然后累加每组的value值。咱们先看看你原来的代码哪里出了问题,再给出几种靠谱的解决方法。

原代码的问题分析

你写的代码有两个核心问题:

  1. 没有初始化一个空哈希来存储分组后的结果,循环里的hash要么被直接赋值为单个元素哈希,要么未定义,导致逻辑完全混乱;
  2. 就算hash存在,你修改的是hash[:value],而不是对应partner_id分组下的value,逻辑方向错了。

方法一:用group_by + map(最简洁直观)

这是Ruby处理分组累加最常用的方式,代码可读性很高:

res = [ 
  {:partner_name=>"company 1", :partner_id=>787, :value=>1}, 
  {:partner_name=>"company 2", :partner_id=>768, :value=>1}, 
  {:partner_name=>"company 3", :partner_id=>769, :value=>1}, 
  {:partner_name=>"company 1", :partner_id=>787, :value=>2} 
]

result = res.group_by { |item| item[:partner_id] }.map do |id, items|
  {
    partner_name: items.first[:partner_name],
    partner_id: id,
    value: items.sum { |item| item[:value] }
  }
end

puts result.inspect
# 输出:[{:partner_name=>"company 1", :partner_id=>787, :value=>3}, {:partner_name=>"company 2", :partner_id=>768, :value=>1}, {:partner_name=>"company 3", :partner_id=>769, :value=>1}]

步骤解释:

  1. group_by { |item| item[:partner_id] }会把原数组按partner_id分组,得到一个键为partner_id、值为对应哈希数组的临时哈希;
  2. 用map遍历这个临时哈希,对每个分组:
    • 取分组内第一个元素的partner_name(默认同一个partner_id对应相同名称,如果有名称不一致的情况,可以额外处理,比如取唯一值);
    • 保留当前分组的partner_id;
    • 用sum累加该分组所有元素的value。

方法二:用each_with_object(更灵活的累加方式)

如果你需要更灵活的逻辑控制,比如处理名称不一致的情况,这个方法更合适:

result = res.each_with_object({}) do |item, hash|
  key = item[:partner_id]
  if hash.key?(key)
    hash[key][:value] += item[:value]
    # 可选:如果存在名称不一致的情况,可以在这里做处理,比如拼接名称
    # hash[key][:partner_name] = "#{hash[key][:partner_name]} / #{item[:partner_name]}"
  else
    hash[key] = item.dup # 复制原哈希,避免修改原数组的元素
  end
end.values

puts result.inspect

步骤解释:

  1. each_with_object({})初始化一个空哈希作为累加容器;
  2. 遍历每个元素,用partner_id作为哈希的键;
  3. 如果键已存在,就累加对应分组的value;如果不存在,就复制当前元素存入哈希(用dup是为了防止后续修改影响原数组的元素);
  4. 最后用.values取出哈希里的所有值,就是我们需要的结果数组。

内容的提问来源于stack exchange,提问作者Mongoid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:50:12