如何将数组中的值按规则求和并转换为Hash结构
按层级分组求和生成嵌套哈希
这个需求挺常见的,咱们可以用哈希(字典)的默认值特性来轻松实现按层级累加数值,下面分别用Ruby和Python给出实现方案:
Ruby 实现
首先定义你的输入数组:
input_array = [ [358, 202102, 5], [358, 202112, 5], [358, 202102, 10], [311, 202103, 5], [311, 202101, 1], [311, 202101, 1], [311, 202115, 8], [311, 202101, 1], [311, 202101, 1] ]
然后用each_with_object配合嵌套的默认哈希来处理:
result = input_array.each_with_object(Hash.new { |h, k| h[k] = Hash.new(0) }) do |(id, period, value), hash| hash[id][period] += value end
代码解释
Hash.new { |h, k| h[k] = Hash.new(0) }:创建一个外层哈希,当访问不存在的key时,会自动生成一个默认值为0的内层哈希,这样就不用手动判断每个层级的key是否存在了。each_with_object:遍历数组的每一项,同时把我们创建的嵌套哈希作为累加容器传递进去。- 每一项被解构为
(id, period, value),直接对hash[id][period]做累加操作——因为内层哈希的默认值是0,第一次访问时会自动初始化为0,加上当前value就完成了求和。
执行后得到的结果就是你要的结构:
# => { 358 => { 202102 => 15, 202112 => 5 }, 311 => { 202103 => 5, 202101 => 4, 202115 => 8 } }
Python 实现
如果用Python的话,可以借助collections.defaultdict来实现类似的逻辑:
首先导入模块并定义输入数组:
from collections import defaultdict input_array = [ [358, 202102, 5], [358, 202112, 5], [358, 202102, 10], [311, 202103, 5], [311, 202101, 1], [311, 202101, 1], [311, 202115, 8], [311, 202101, 1], [311, 202101, 1] ]
然后处理数据:
# 嵌套的defaultdict,外层的默认值是一个int类型的defaultdict result = defaultdict(lambda: defaultdict(int)) for id_num, period, value in input_array: result[id_num][period] += value # 可选:转换成普通字典(如果不需要defaultdict的特性) result = {k: dict(v) for k, v in result.items()}
代码解释
defaultdict(lambda: defaultdict(int)):外层字典的默认值是一个默认值为0的内层字典,同样避免了手动判断key是否存在的麻烦。- 遍历数组时直接解构每一项,对对应层级的数值做累加即可。
- 最后如果需要转换成普通的Python字典,用字典推导式处理一下就行。
执行后得到的结果和需求一致:
# {358: {202102: 15, 202112: 5}, 311: {202103: 5, 202101: 4, 202115: 8}}
内容的提问来源于stack exchange,提问作者caramba
相关产品推荐
相关产品推荐

