有没有更短的方法来编写此哈希合并?

时间:2019-03-27 18:09:39

标签: ruby-on-rails ruby

我有两个哈希。第一个哈希值应优先。仅当其为nil或空白时,才应使用第二个哈希值覆盖。

main_hash.merge!(option_hash) do |key, main_hash, option_hash|
  main_hash.presence || option_hash.presence
end

3 个答案:

答案 0 :(得分:2)

使用您的代码,这很好,但是对块和较短的块变量使用大括号。而且您不需要第二个presence

main_hash.merge!(option_hash){|_k, h1, h2| h1.presence || h2}
带有块的

#merge!(和#merge)仅调用该块以处理两个哈希中都存在键的情况。如果option_hash中没有main_hash键,则只需插入键/值对。

您可以将#merge!与代码块配合使用,以完成一些巧妙的技巧,例如设置哈希值的总和。

hash_1 = {a: 1, b: 1, c: 1}
hash_2 = {b: 1, c: 1, d: 1}

hash_1.merge!(hash_2{|_k, v1, v2| v1 + v2}
=> {:a => 1, :b => 2, :c => 2, :d => 1}

答案 1 :(得分:1)

这是较短的,但我认为您的方法更具可读性。

main_hash   = {a:1, b:nil, c:3}
option_hash = {a:5, b:2, c:8}

main_hash   = option_hash.merge(main_hash.reject{|_,v| v.blank?})

#=> {a:1, b:2, c:3}

您可以通过这种方式进行操作,并为结果提供一个变量名称,这样可以使发生的事情变得更加清晰merged_main_option_hash,而不仅仅是main_hash

答案 2 :(得分:0)

[1] pry(main)> main_hash = { key1: 1, key2: 2, key3: '', key4: nil }
=> {:key1=>1, :key2=>2, :key3=>"", :key4=>nil}
[2] pry(main)> option_hash = { key2: 2.2, key3: 3, key4: 4 }
=> {:key2=>2.2, :key3=>3, :key4=>4}
[3] pry(main)> main_hash.reject!{ |key, value| value.blank? }.merge!(option_hash) { |key, main_hash_value, option_hash_value| main_hash_value }
=> {:key1=>1, :key2=>2, :key3=>3, :key4=>4}
[4] pry(main)> 

有关更多详细信息,请参见apidock:merge!apidock:reject!