通过布尔运算合并两个布尔值哈希的 Ruby 惯用方法是什么?
What is the Ruby idiomatic way to merge two hashes of boolean values over boolean operations?
这是目标:
a={a:true, b:true, c:true, d:false, e:false, g:false, h:nil, i:nil, j:nil}
b={a:true, b:false, c:nil, d:true, e:false, g:nil, h:true, i:false, j:nil}
c={a:true, b:false, c:nil, d:false, e:false, g:nil, h:nil, i:nil, j:nil}
conjonctive_map(a, b) == c # expect to be true
所以问题是,在 Ruby 中实现该目标的惯用方法是什么?它不必是 conjonctive_map
定义的方法、内联 .map
或类似的方法。在我的情况下也可以进行任何涉及 nil
到 return false
的操作,我提出了一个 c
总是以 nil
结束。
a={a:true, b:true, c:true, d:false, e:false, g:false, h:nil, i:nil, j:nil}
b={a:true, b:false, c:nil, d:true, e:false, g:nil, h:true, i:false, j:nil}
a.merge(b) { |_, v1, v2| v1 && v2 }
#⇒ {:a=>true, :b=>false, :c=>nil, :d=>false,
# :e=>false, :g=>false, :h=>nil, :i=>nil, :j=>nil}
如果出于某种原因您希望 nil
优先于 false
,请明确执行此操作:
c={a:true, b:false, c:nil, d:false, e:false, g:nil, h:nil, i:nil, j:nil}
a.merge(b) { |_, v1, v2| [v1, v2].any?(&:nil?) ? nil : v1 && v2 }
_ == c
#⇒ true
a = { a:true, b:true, c:true, d:false, e:false, g:false, h:nil, i:nil, j:nil }
b = { b:false, a:true, c:nil, d:true, e:false, g:nil, h:true, i:false, j:nil }
values = b.values_at(*a.keys)
#=> [true, false, nil, true, false, nil, true, false, nil]
a.transform_values { |v| v && values.shift }
#=> {:a=>true, :b=>false, :c=>nil, :d=>false, :e=>false, :g=>false, :h=>nil,
# :i=>nil, :j=>nil}
参见 Hash#transform_values,它在 Ruby v2.4 中首次亮相。
如果只返回 true
和 false
,请将 &&
替换为 &
。参见 TrueClass#&, FalseClass#& and NilClass#&。
这是目标:
a={a:true, b:true, c:true, d:false, e:false, g:false, h:nil, i:nil, j:nil}
b={a:true, b:false, c:nil, d:true, e:false, g:nil, h:true, i:false, j:nil}
c={a:true, b:false, c:nil, d:false, e:false, g:nil, h:nil, i:nil, j:nil}
conjonctive_map(a, b) == c # expect to be true
所以问题是,在 Ruby 中实现该目标的惯用方法是什么?它不必是 conjonctive_map
定义的方法、内联 .map
或类似的方法。在我的情况下也可以进行任何涉及 nil
到 return false
的操作,我提出了一个 c
总是以 nil
结束。
a={a:true, b:true, c:true, d:false, e:false, g:false, h:nil, i:nil, j:nil}
b={a:true, b:false, c:nil, d:true, e:false, g:nil, h:true, i:false, j:nil}
a.merge(b) { |_, v1, v2| v1 && v2 }
#⇒ {:a=>true, :b=>false, :c=>nil, :d=>false,
# :e=>false, :g=>false, :h=>nil, :i=>nil, :j=>nil}
如果出于某种原因您希望 nil
优先于 false
,请明确执行此操作:
c={a:true, b:false, c:nil, d:false, e:false, g:nil, h:nil, i:nil, j:nil}
a.merge(b) { |_, v1, v2| [v1, v2].any?(&:nil?) ? nil : v1 && v2 }
_ == c
#⇒ true
a = { a:true, b:true, c:true, d:false, e:false, g:false, h:nil, i:nil, j:nil }
b = { b:false, a:true, c:nil, d:true, e:false, g:nil, h:true, i:false, j:nil }
values = b.values_at(*a.keys)
#=> [true, false, nil, true, false, nil, true, false, nil]
a.transform_values { |v| v && values.shift }
#=> {:a=>true, :b=>false, :c=>nil, :d=>false, :e=>false, :g=>false, :h=>nil,
# :i=>nil, :j=>nil}
参见 Hash#transform_values,它在 Ruby v2.4 中首次亮相。
如果只返回 true
和 false
,请将 &&
替换为 &
。参见 TrueClass#&, FalseClass#& and NilClass#&。