ruby-on-rails - 明智地合并两个哈希数组
问题描述
我正在尝试组合两个哈希数组 arr1 和 arr2:
arr1 = [{"id"=>1, "a"=>1, "c"=>2}, {"id"=>2, "a"=>1}]
arr2 = [{"id"=>1, "a"=>10, "b"=>20}, {"id"=>3, "b"=>2}]
而且我希望结果包含两个数组中的所有元素,但是对于“id”键具有相同值的元素应该合并,以便如果两个哈希中都存在一个键,则应该从 arr2 中选择它,否则,它只是从密钥所在的任何哈希中选择值。因此,上面示例的组合将是:
combined = [
{"id"=>1, "a"=>10, "b"=>20, "c"=>2}, # "id"=>1 exists in both, so they are merged
{"id"=>2, "a"=>1},
{"id"=>3, "b"=>2}
]
下面的代码有效,但我是 Ruby 新手,我确信有更好的方法来做到这一点。你能提供一个更红宝石的方式吗?
combined = []
# merge items that exist in both and add to combined
arr1.each do |a1|
temp = arr2.select {|a2| a2["id"] == a1["id"]}[0]
if temp.present?
combined << temp.reverse_merge(a1)
end
end
# Add items that exist in arr1 but not in arr2
arr1.each do |a1|
if arr2.pluck("id").exclude? a1["id"]
combined << a1
end
end
# Add items that exist in arr2 but not in arr1
arr2.each do |a2|
if arr1.pluck("id").exclude? a2["id"]
combined << a2
end
end
解决方案
我假设 和 的两个元素(散列)不具有arr1
的属性。g
h
g["id"] == h["id"]
在这种情况下,可以写:
(arr1 + arr2).each_with_object(Hash.new { |h,k| h[k] = {} }) { |g,h|
h[g["id"]].update(g) }.values
#=> [{"id"=>1, "a"=>10, "c"=>2, "b"=>20}, {"id"=>2, "a"=>1},
# {"id"=>3, "b"=>2}]
注意:
(arr1 + arr2).each_with_object(Hash.new { |h,k| h[k] = {} }) { |g,h|
h[g["id"]].update(g) }
#=> {1=>{"id"=>1, "a"=>10, "c"=>2, "b"=>20}, 2=>{"id"=>2, "a"=>1},
# 3=>{"id"=>3, "b"=>2}}
如果定义了哈希:
h = Hash.new { |h,k| h[k] = {} }
然后,可能在将键添加到 之后h
,如果h
没有键k
,h[k] = {}
则执行并返回空哈希。请参阅采用块的Hash::new形式。另请参阅Hash#update(又名Hash#merge!
)。
也可以写成:
(arr1 + arr2).each_with_object({}) { |g,h| (h[g["id"]] ||= {}).update(g) }.values
#=> {1=>{"id"=>1, "a"=>10, "c"=>2, "b"=>20}, 2=>{"id"=>2, "a"=>1},
# 3=>{"id"=>3, "b"=>2}}
另一种方法是使用Emumerable#group_by,其中分组在 key 的值上"id"
:
(arr1 + arr2).group_by { |h| h["id"] }.values.map { |a| a.reduce(&:merge) }
#=> [{"id"=>1, "a"=>10, "c"=>2, "b"=>20}, {"id"=>2, "a"=>1}, {"id"=>3, "b"=>2}]
推荐阅读
- java - 我似乎无法修复这个空指针异常错误,为什么我会得到它?
- qt - QT堆叠小部件继承父样式表#
- javascript - 按两个值过滤firebase数据库
- ceph - Cephadm orch 守护进程添加 osd 挂起
- r - 未保存为 R 文件时如何在 R Shiny 中显示图像?
- c++ - 为 64 位版本构建 WxWidgets 应用程序时出现 Visual Studio 2019 错误
- computer-vision - Yolov4 自定义训练 - 无法打开文件:data/obj.data
- r - 如何在R的散点图中输入相同的y轴值?
- java - 在类路径资源 [com/realpage/propertyware/resources/configuration/spring/services.xml] 中定义名称为“utilService”的 bean 创建错误
- javascript - onload 事件在填充 div 之前完成