Ruby哈希数组按指定键分组合并并求其他键平均值的优化需求
合并Ruby哈希数组中同
acc_id元素并计算平均值 如果你需要把数组里:acc_id相同的哈希合并,对其他字段求平均值,原有的实现确实可以简化不少。这里给你一个更简洁优雅的Ruby风格解决方案:
输入数据
首先看一下我们要处理的原始数据:
require 'pp' arr = [ {:red=>346.0, :unu=>10.0, :used=>20147.0, :acc_id=>550, :percent=>0.01}, {:red=>0.0, :unu=>1.0, :used=>66.0, :acc_id=>550, :percent=>0.06}, {:red=>120.0, :unu=>11.0, :used=>166.0, :acc_id=>550, :percent=>10.06}, {:red=>1306.0, :unu=>1.0, :used=>13259.0, :acc_id=>9999, :percent=>0.0} ]
优化后的实现
result = arr.group_by { |h| h[:acc_id] }.map do |acc_id, hashes| count = hashes.size # 第一步:累加同组内所有哈希的对应键值 summed = hashes.inject({}) do |memo, hash| hash.each { |k, v| memo[k] = (memo[k] || 0) + v } memo end # 第二步:对非acc_id的键计算平均值,保留acc_id原值 summed.each_with_object({}) do |(k, v), avg_hash| avg_hash[k] = k == :acc_id ? v : v.to_f / count end end pp result
代码逻辑拆解
- 分组:用
group_by { |h| h[:acc_id] }把数组按:acc_id分组,得到一个键为acc_id、值为对应哈希数组的结构,这样我们就能批量处理同ID的元素。 - 累加求和:通过
inject遍历每个分组里的哈希,把每个键的值累加起来,得到每个字段的总和。 - 计算平均值:用
each_with_object遍历累加后的哈希,对:acc_id直接保留原值,其他字段用总和除以分组内元素的数量得到平均值。
为什么这个实现更优?
- 原实现里需要判断处理后的结果是哈希还是数组,逻辑冗余;这里通过链式调用
group_by+map,流程更清晰,没有多余的分支判断。 - 用Ruby原生的枚举方法(
inject、each_with_object)替代手动修改哈希,代码更符合Ruby的"优雅"风格,可读性和维护性更强。 - 把"求和"和"求平均"拆成两个明确的步骤,逻辑更直观,不容易出错。
运行结果
执行后你会得到预期的输出:
[ {:red=>155.33333333333334, :unu=>7.333333333333333, :used=>6793.0, :acc_id=>550, :percent=>3.376666666666667}, {:red=>1306.0, :unu=>1.0, :used=>13259.0, :acc_id=>9999, :percent=>0.0} ]
内容的提问来源于stack exchange,提问作者pencilcucumber
相关产品推荐
相关产品推荐

