Ruby - 合并两个哈希并维护有序键

时间:2015-10-08 20:41:59

标签: ruby hash key

我有两个哈希:

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方法或实用程序可以更清洁的方式完成同样的任务?

3 个答案:

答案 0 :(得分:2)

(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"}

答案 1 :(得分:1)

首先创建一个包含哈希值的数组。这可以使用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"}

答案 2 :(得分:1)

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"}