Ruby中如何将哈希转换为值为累计求和的新哈希
最优实现方案
推荐用each_with_object搭配外部累计变量,一次遍历即可完成,逻辑清晰性能好:
data = {:a => 2, :b => 8, :c => 10, :d => 40 } current_sum = 0 result = data.each_with_object({}) do |(key, value), hash| current_sum += value hash[key] = current_sum end # 输出结果: {:a=>2, :b=>10, :c=>20, :d=>60}
如果偏好只用inject的写法,可以用数组同时承载累计值和结果哈希,不需要额外外部变量:
result = data.inject([0, {}]) do |(sum, res_hash), (key, value)| new_sum = sum + value res_hash[key] = new_sum [new_sum, res_hash] end.last
原写法错误原因
你之前的inject逻辑出错的核心原因是:每次迭代都对result.values做全量求和,相当于重复计算了所有历史值的总和:
- 处理键
:c时,结果哈希里已经存了:a=>2, :b=>10,全量求和得到12,加上当前值10得到22,和预期的20不符 - 不仅结果错误,时间复杂度也变成O(n²),数据量大的时候性能会很差
你之前的实现需要两次遍历(一次算累计数组,一次转哈希),上面的两种方案都只需要一次遍历,效率更高,写法也更简洁。
内容的提问来源于stack exchange,提问作者RJaus
相关产品推荐
相关产品推荐

