如何基于现有哈希数组创建指定结构的新哈希表?
解决Ruby哈希数组的整合问题
首先咱们先理清楚需求,再拆解现有代码的问题,最后给出可行的实现方案:
需求回顾
你手里的哈希数组包含不同服务的运行数据,需要完成两个核心操作:
- 把所有
name为"frontend"的数据合并(对session_total和byte字段求和),整理到:frontend键下 - 把
name为"backend"的数据作为:details,name为"backend_stagging"的数据作为:summary,整合到:backend键下
现有代码的问题
你用select方法来处理数据,但select的作用是筛选数组元素,不是用来构建新哈希的,而且代码里还有几个明显的问题:
- 在
select块里用return会直接终止整个方法,没法完成遍历处理 - 错误地引用数组
hashed_data的键,应该用块变量h访问单个哈希的字段(比如h[:name]而非hashed_data[:name]) - 语法错误:比如
h[:name == "backend")的括号不匹配,还有[:session_total => ...]这种错误的哈希写法
正确实现方案
咱们用Ruby的枚举方法分步处理,逻辑更清晰:
hashed_data = [ {:name => "frontend", :session_total => 145, :byte => 54667}, {:name => "backend_stagging", :session_total => 546, :byte => 895747}, {:name => "backend", :session_total => 5468, :byte => 8957447}, {:name => "frontend", :session_total => 54, :byte => 67387} ] # 处理frontend:合并所有frontend的session_total和byte frontend_entries = hashed_data.select { |h| h[:name] == "frontend" } frontend_summary = frontend_entries.each_with_object({session_total: 0, byte: 0}) do |entry, sum| sum[:session_total] += entry[:session_total] sum[:byte] += entry[:byte] end frontend_data = { name: "frontend", summary: frontend_summary } # 处理backend:分别提取backend和backend_stagging的数据 backend_entry = hashed_data.find { |h| h[:name] == "backend" } backend_stagging_entry = hashed_data.find { |h| h[:name] == "backend_stagging" } backend_data = { name: "backend", details: {session_total: backend_entry[:session_total], byte: backend_entry[:byte]}, summary: backend_stagging_entry } # 整合最终哈希 hashed_data_modify = { frontend: frontend_data, backend: backend_data } # 查看结果 p hashed_data_modify
代码解释
- Frontend处理:
- 先用
select筛选出所有frontend的条目 - 再用
each_with_object遍历这些条目,对session_total和byte字段求和,得到汇总数据
- 先用
- Backend处理:
- 用
find分别定位backend和backend_stagging的单个条目 - 按照需求把它们分别放到
:details和:summary键下
- 用
- 结果整合:把处理好的两部分数据组合成最终目标哈希
补充说明
你给出的目标示例里frontend的session_total写的是546,这和原始数据145+54=199不符,我这里是按照求和合并的逻辑实现的,如果你的需求不是求和(比如取最大值/最新数据),直接修改frontend_summary的处理逻辑即可~
内容的提问来源于stack exchange,提问作者Matthew Michael Sawczuk
相关产品推荐
相关产品推荐

