我有两个相同长度的哈希:
hash1 = {"1"=>"val", "2"=>"val", "3"=>"", "4"=>""}
hash2 = {"1"=>[""], "2"=>["value"], "3"=>["val1", "val2"], "4"=>[""]}
我需要比较它们。相应的键要么都具有值(对于hash1
,这意味着非空白,对于hash2
,这意味着数组中必须存在非空值)或两者都有空值(对于hash2
,这意味着值为[""])。
"1"
失败(数组有一个值,该值为空)"2"
次传递(都有值)"3"
失败(hash1
为空白)"4"
次传递(hash1
为空,hash2
在数组中有一个值且该值为空白如果其中一个比较失败,那么我应该返回false
。我不确定如何做这样的比较。
答案 0 :(得分:2)
假设已经订购了哈希:
hash1 = {"1"=>"val", "2"=>"val", "3"=>"", "4"=>""}
hash2 = {"1"=>[""], "2"=>["value"], "3"=>["val1", "val2"], "4"=>[""]}
hash1.zip(hash2).all? do |(_, fv), (_, lv)|
fv.empty? ^ !lv.all?(&:empty?)
end
在这里,我们可以使用XOR
。无论是否排序哈希,都需要预处理(排序)。
根据@ sawa和@ CarySwoveland的评论,对于没有排序的哈希:
hash1.sort.zip(hash2.sort).all? do |(fk, fv), (lk, lv)|
# ⇓ consistency ⇓ true if one operand is truthy, other is falsey
(fk == lk) && (fv.empty? ^ !lv.all?(&:empty?))
end
答案 1 :(得分:1)
编辑:更好,我认为:
hash1.all? { |k,v| !(v.empty? ^ (hash2[k]==[""])) }
#=> false
原始答案:
keys = hash1.keys
#=> ["1", "2", "3", "4"]
hash1.values_at(*keys).zip(hash2.values_at(*keys)).all? do |v1,v2|
!(v1.empty? ^ (v2==[""]))
end
#=> false
^
是Ruby的XOR运算符。
答案 2 :(得分:1)
hash1.merge(hash2){|_, v1, v2| v2.dup.push(v1)}
.all?{|_, v| v.all?(&:empty?) or v.none?(&:empty?)}
或者关注@ mudasobwa的建议:
hash2.merge(hash1){|_, v2, *v1| v1 + v2}
.all?{|_, v| v.all?(&:empty?) or v.none?(&:empty?)}
答案 3 :(得分:0)
另一种方法:
def compare_hashes(hash1, hash2)
(1..hash1.length).each do |n|
n = n.to_s # can easily swap this if you want to use integers or symbols
return false if hash1[n].empty? || hash2[n].empty? || hash2[n].all?(&:empty?)
end
true
end
答案 4 :(得分:0)
以下内容或多或少是对要求的直接翻译。(*)
# similar(h1,h2) assumes that h1 is a string-valued hash,
# and that h2 is a hash with values that are all arrays of strings.
#
def similar(h1,h2)
return false if h1.length != h2.length
h1.all? {|key, v1|
v2=h2[key]
v2 != nil and
((v1=="" and v2==[""]) or
(v1 != "" and !v2.all?{|x| x.length==0} ))
}
end
(*)OP规定两个哈希值具有相同数量的键,因此可以省略检查该情况,但检查没有任何损害,所写的方法是包括检查可能会更有用(或至少更现实)。随意省略它。