Ruby 检查哈希值是否都为空或都有值
我有两个长度相同的散列:Ruby 检查哈希值是否都为空或都有值,ruby,hash,Ruby,Hash,我有两个长度相同的散列: hash1 = {"1"=>"val", "2"=>"val", "3"=>"", "4"=>""} hash2 = {"1"=>[""], "2"=>["value"], "3"=>["val1", "val2"], "4"=>[""]} 我需要比较一下。相应的键需要两者都有一个值(对于hash1,这意味着非空;对于hash2,这意味着数组中必须有一个非空值),或者两者都有一个空值(对于hash2,这意味着值为[“
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
。我不知道如何进行这样的比较。假设哈希已经排序:
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
假设哈希已排序:
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
编辑:更好,我认为:
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运算符。编辑:更好,我认为:
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运算符。另一种方法:
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
另一种方法:
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
以下或多或少是需求的直接翻译。(*)
(*)OP规定两个散列具有相同数量的键,因此可能可以省略这种情况下的检查,但检查没有害处,并且所编写的方法在包含检查的情况下可能更有用(或至少更现实)。请随意省略。以下或多或少是需求的直接翻译。(*)
hash1.merge(hash2){|_, v1, v2| v2.dup.push(v1)}
.all?{|_, v| v.all?(&:empty?) or v.none?(&:empty?)}
(*)OP规定两个散列具有相同数量的键,因此可能可以省略这种情况下的检查,但检查没有害处,并且所编写的方法在包含检查的情况下可能更有用(或至少更现实)。可以省略它
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?)}
或者按照@mudasobwa的建议:
hash2.merge(hash1){|_, v2, *v1| v1 + v2}
.all?{|_, v| v.all?(&:empty?) or v.none?(&:empty?)}
不清楚您所说的“
hash2
有一个值且该值为空”是什么意思。也许您所说的“(需要其中之一)都有一个值(…)”是指其他内容。当这个条件满足时,另一个条件总是满足的。@sawa我更新了它。希望它能更清楚地解释为什么会通过。散列的整数键总是在1到散列长度的范围内吗?值是否总是hash1中的字符串和包含hash2中字符串的数组?如果hash1={“1”=>“}
和hash2={“1”=>[”,“]}
?不清楚您所说的“hash2
有一个值而该值为空”是什么意思。也许您的意思是“(需要其中一个)都有一个值(…)”。当这个条件满足时,另一个条件总是满足的。@sawa我更新了它。希望它能更清楚地解释为什么会通过。散列的整数键总是在1到散列长度的范围内吗?值是否总是hash1中的字符串和包含hash2中字符串的数组?如果hash1={“1”=>“}
和hash2={“1”=>[“”,”“]}
?通过对块变量配置文件进行更详细的阐述,您可以摆脱map
、first
和last
@sawa确实,谢谢。毕竟(请阅读:根据您的建议),这似乎是一个很好的解决方案。我们似乎一直在按照同样的思路思考。这取决于两个散列中的键顺序相同。@CarySwoveland这是OP的错。如果OP意味着订单没有保证,那么OP应该给出一个随机订单的例子。这是误导。同时,OP从未写过订单,因此您的解释也是合理的。@CarySwoveland。毕竟。我在回答中删除了一条关于排序的评论。通过对块变量配置文件进行更详细的阐述,您可以摆脱映射
、第一次
、和最后一次
@sawa。确实,谢谢您。毕竟(请阅读:根据您的建议),这似乎是一个很好的解决方案。我们似乎一直在按照同样的思路思考。这取决于两个散列中的键顺序相同。@CarySwoveland这是OP的错。如果OP意味着订单没有保证,那么OP应该给出一个随机订单的例子。这是误导。同时,OP从未写过订单,因此您的解释也是合理的。@CarySwoveland。毕竟。我在回答中删除了一条关于排序的评论。Cary可能是假设哈希中的顺序不能保证。如果是,它可以变成hash1.values.zip(hash2.values).
。我认为您的v2.empty?
部分不正确。不止这些。不应该v2.空吗?
应该!v2.all(&:empty?
?@sawa,是的,我在中使用了值,因为我没有假设键的顺序。@sawa,在排序
中是的,但我假设值在
中更快。Cary可能假设哈希中的顺序没有保证。如果是,它可以变成hash1.values.zip(hash2.values).
。我认为您的v2.empty?
部分不正确。不止这些。不应该v2.空吗?
应该!v2.all(&:empty?
?@sawa,是的,我在
中使用了值,因为我没有假设键的顺序。@sawa,ye