Ruby - 合并两个散列并维护有序键
Ruby - Merge two hashes and maintain ordered keys
我有两个哈希:
a = {"0"=>"name", "1"=>"email"}
b = {"0"=>"source", "1"=>"info", "2"=>"extra", "3"=>"name"}
我想要通过执行以下操作创建的哈希:
1) 当两个哈希包含相同的值时,保留原始哈希的值并丢弃第二个哈希的值。
2) 当第二个哈希的值不在第一个哈希中时,只需添加到新哈希的末尾,确保键是有序的。
结果为:
{"0"=>"name", "1"=>"email", "2"=>"source", "3"=>"info", "4"=>"extra"}
我这样做很丑陋:
l1 = a.keys.length
l2 = b.keys.length
max = l1 > l2 ? l1 : l2
counter = l1
result = {}
max.times do |i|
unless a.values.include? b[i.to_s]
result[counter.to_s] = b[i.to_s]
counter += 1
end
end
a.merge!(result)
是否有内置的 ruby 方法或实用程序可以更简洁地完成同样的任务?
(a.values + b.values).uniq.map.with_index{|v, i| [i.to_s, v]}.to_h
# => {"0"=>"name", "1"=>"email", "2"=>"source", "3"=>"info", "4"=>"extra"}
首先创建一个包含哈希值的数组。这可以通过 concat
方法来完成。现在我们有了一个数组,我们可以调用 uniq
方法来检索所有唯一值。这也保留了顺序。
a = { "0" => "name", "1" => "email" }
b = { "0" => "source", "1" => "info", "2" => "extra", "3" => "name" }
values = a.values.concat(b.values).uniq
在 Ruby 中生成哈希的捷径就是这个技巧。
Hash[[*0..values.length-1].zip(values)]
输出:
{0=>"name", 1=>"email", 2=>"source", 3=>"info", 4=>"extra"}
a = {"0"=>"name", "1"=>"email"}
b = {"0"=>"source", "1"=>"info", "2"=>"extra", "3"=>"name"}
key = (a.size-1).to_s
#=> "1"
b.each_value.with_object(a) { |v,h| (h[key.next!] = v) unless h.value?(v) }
#=> {"0"=>"name", "1"=>"email", "2"=>"source", "3"=>"info", "4"=>"extra"}
我有两个哈希:
a = {"0"=>"name", "1"=>"email"}
b = {"0"=>"source", "1"=>"info", "2"=>"extra", "3"=>"name"}
我想要通过执行以下操作创建的哈希:
1) 当两个哈希包含相同的值时,保留原始哈希的值并丢弃第二个哈希的值。
2) 当第二个哈希的值不在第一个哈希中时,只需添加到新哈希的末尾,确保键是有序的。
结果为:
{"0"=>"name", "1"=>"email", "2"=>"source", "3"=>"info", "4"=>"extra"}
我这样做很丑陋:
l1 = a.keys.length
l2 = b.keys.length
max = l1 > l2 ? l1 : l2
counter = l1
result = {}
max.times do |i|
unless a.values.include? b[i.to_s]
result[counter.to_s] = b[i.to_s]
counter += 1
end
end
a.merge!(result)
是否有内置的 ruby 方法或实用程序可以更简洁地完成同样的任务?
(a.values + b.values).uniq.map.with_index{|v, i| [i.to_s, v]}.to_h
# => {"0"=>"name", "1"=>"email", "2"=>"source", "3"=>"info", "4"=>"extra"}
首先创建一个包含哈希值的数组。这可以通过 concat
方法来完成。现在我们有了一个数组,我们可以调用 uniq
方法来检索所有唯一值。这也保留了顺序。
a = { "0" => "name", "1" => "email" }
b = { "0" => "source", "1" => "info", "2" => "extra", "3" => "name" }
values = a.values.concat(b.values).uniq
在 Ruby 中生成哈希的捷径就是这个技巧。
Hash[[*0..values.length-1].zip(values)]
输出:
{0=>"name", 1=>"email", 2=>"source", 3=>"info", 4=>"extra"}
a = {"0"=>"name", "1"=>"email"}
b = {"0"=>"source", "1"=>"info", "2"=>"extra", "3"=>"name"}
key = (a.size-1).to_s
#=> "1"
b.each_value.with_object(a) { |v,h| (h[key.next!] = v) unless h.value?(v) }
#=> {"0"=>"name", "1"=>"email", "2"=>"source", "3"=>"info", "4"=>"extra"}