我不确定我是否理解这个问题,但我希望您可能正在寻找以下内容。
arr = [
["ABC", "5A2", nil, "88474"],
["ABC", nil, "2", "88474"],
["ABC", nil, nil, "88474"],
["ABC", nil, nil, "88474"],
["Jack", "5A2", nil, "05195"],
["Jack", nil, "2", "05195"],
["Jack", nil, nil, "05195"],
["Jack", nil, nil, "05195"]
]
arr.each_with_object({}) do |a, h|
h.update(a.first=>a) { |_k, oa, na| oa.zip(na).map { |ov, nv| ov.nil? ? nv : ov } }
end.values
#=> [["ABC", "5A2", "2", "88474"], ["Jack", "5A2", "2", "05195"]]
这使用了Hash#update(又名merge!)的形式,它使用了块
{ |_k, oa, na| oa.zip(na).map { |ov, nv| ov.nil? ? nv : ov } }
确定正在构建的哈希 (h) 和正在合并的哈希 ({ a.first=>a }) 中存在的键的值。有关三个块变量 _k、oa 和 na 的说明,请参阅文档。1
我可以通过使用 puts 语句加盐代码并使用缩写数组 arr 运行它来最好地解释计算是如何进行的。
arr = [
["ABC", "5A2", nil, "88474"],
["ABC", nil, "2", "88474"],
["Jack", "5A2", nil, "05195"],
["Jack", nil, "2", "05195"],
]
arr.each_with_object({}) do |a, h|
puts "\na = #{a}"
puts "h = #{h}"
puts "a.first=>a = #{a.first}=>#{a}"
h.update(a.first=>a) do |_k, oa, na|
puts "_k = #{_k}"
puts "oa = #{oa}"
puts "na = #{na}"
a = oa.zip(na)
puts "oa.zip(na) = #{a}"
a.map do |ov, nv|
puts " ov = #{ov}, nv = #{nv}"
puts " ov.nil? ? nv : ov = #{ov.nil? ? nv : ov}"
ov.nil? ? nv : ov
end
end
end.tap { |h| puts "h = #{h}" }.values
#=> [["ABC", "5A2", "2", "88474"], ["Jack", "5A2", "2", "05195"]]
显示如下。
a = ["ABC", "5A2", nil, "88474"]
h = {}
a.first=>a = ABC=>["ABC", "5A2", nil, "88474"]
(The block is not called here because h does not have a key "ABC")
a = ["ABC", nil, "2", "88474"]
h = {"ABC"=>["ABC", "5A2", nil, "88474"]}
a.first=>a = ABC=>["ABC", nil, "2", "88474"]
_k = ABC
oa = ["ABC", "5A2", nil, "88474"]
na = ["ABC", nil, "2", "88474"]
oa.zip(na) = [["ABC", "ABC"], ["5A2", nil], [nil, "2"], ["88474", "88474"]]
ov = ABC, nv = ABC
ov.nil? ? nv : ov = ABC
ov = 5A2, nv =
ov.nil? ? nv : ov = 5A2
ov = , nv = 2
ov.nil? ? nv : ov = 2
ov = 88474, nv = 88474
ov.nil? ? nv : ov = 88474
a = ["Jack", "5A2", nil, "05195"]
h = {"ABC"=>["ABC", "5A2", "2", "88474"]}
a.first=>a = Jack=>["Jack", "5A2", nil, "05195"]
(The block is not called here because h does not have a key "Jack")
a = ["Jack", nil, "2", "05195"]
h = {"ABC"=>["ABC", "5A2", "2", "88474"], "Jack"=>["Jack", "5A2", nil, "05195"]}
a.first=>a = Jack=>["Jack", nil, "2", "05195"]
_k = Jack
oa = ["Jack", "5A2", nil, "05195"]
na = ["Jack", nil, "2", "05195"]
oa.zip(na) = [["Jack", "Jack"], ["5A2", nil], [nil, "2"], ["05195", "05195"]]
ov = Jack, nv = Jack
ov.nil? ? nv : ov = Jack
ov = 5A2, nv =
ov.nil? ? nv : ov = 5A2
ov = , nv = 2
ov.nil? ? nv : ov = 2
ov = 05195, nv = 05195
ov.nil? ? nv : ov = 05195
h = {"ABC"=>["ABC", "5A2", "2", "88474"], "Jack"=>["Jack", "5A2", "2", "05195"]}
1.按照惯例,我在公共密钥名称_k 的开头加上一个下划线,以向读者表明它不用于块计算。通常你会看到这样一个单独用下划线表示的块变量。