Ruby On Rails中按指定字段合并跨库查询的对象数组
合并两个数据库查询结果数组(按指定字段匹配合并)
核心实现思路
先将其中一个数组转换为以匹配字段为键的哈希,实现O(1)时间复杂度的快速查找,避免嵌套循环的低效;然后遍历另一个数组完成匹配合并,最后保留未匹配的元素即可。
具体代码实现
假设你的两个查询结果分别是sql1_result和sql2_result:
# 1. 将SQL2结果转成以externalName为键的哈希,方便快速定位匹配项 sql2_lookup = sql2_result.each_with_object({}) do |item, hash| hash[item[:externalName]] = item end # 2. 遍历SQL1结果,匹配合并已找到的项,同时移除哈希中已匹配的元素 merged_sql1_items = sql1_result.map do |item| # 找到匹配项则合并,并从哈希中删除(避免重复匹配) if matched_item = sql2_lookup.delete(item[:name]) item.merge(matched_item) else item # 无匹配则保留原元素 end end # 3. 合并处理后的SQL1元素和SQL2中未匹配的剩余元素 final_result = merged_sql1_items + sql2_lookup.values
用你的示例数据验证
输入:
sql1_result = [{id1: 1, name: 'john', role: 'user'}, {id1: 2, name: 'matt', role: 'admin'}] sql2_result = [{id2: 4, externalName: 'john'}, {id2: 8, externalName: 'ronald'}]
执行代码后,final_result的结果完全符合你的期望:
[ {id1: 1, name: 'john', role: 'user', id2: 4}, {id1: 2, name: 'matt', role: 'admin'}, {id2: 8, externalName: 'ronald'} ]
补充说明
- 针对你尝试过的方法的补充:
concat仅做数组拼接,无匹配逻辑,无法满足需求;merge是单个哈希的方法,不能直接作用于数组,且无法批量处理匹配逻辑;map可以用,但需要搭配哈希映射来避免重复处理和遗漏未匹配项,上面的实现已经包含了map的合理用法。
- 性能优势:用哈希做查找的时间复杂度为O(n+m)(n、m分别为两个数组的长度),远优于嵌套循环的O(n*m),数据量大时优势明显;
- 多匹配场景:如果SQL2中有多个相同
externalName的元素,上述代码只会匹配第一个(因哈希键唯一)。若需处理一对多匹配,可将哈希值改为数组,再用flat_map替代map逐个合并。
内容的提问来源于stack exchange,提问作者cctake2it
相关产品推荐
相关产品推荐

