如何跳过`zip`中的第一对?

时间:2016-03-03 03:15:02

标签: ruby iterator

以下代码比较了两个哈希:一个以字符串作为值,另一个以数组作为值。

hash1 = {"1"=>"val", "2"=>"val", "3"=>"vall", "4"=>""} 
hash2 = {"1"=>[""], "2"=>["value"], "3"=>["val1", "val2"], "4"=>[""]} 

unless hash1.zip(hash2).all? { |(_, fv), (_, lv)|  fv.empty? ^ !lv.all?(&:empty?) }
  ...
end

如果hash1的字符串为空,hash2有值,反之亦然,则为false。

我需要比较以跳过两个哈希中的第一个元素。我会添加with_index来执行此操作,但我不知道如何添加它,或者在这种情况下它是否是最佳方式。

2 个答案:

答案 0 :(得分:2)

zip的结果是一个数组,所以只是切断了头部:

hash1.zip(hash2).drop(1).all? { ... }

您不能使用with_index,因为any?map和其他人不同,不会返回Enumerator。你可以做一个解决方法:

hash1.zip(hash2).map.with_index { |((_, fv), (_, lv)), i|
  i.zero? || fv.empty? ^ !lv.all?(&:empty?)
}.all?

但这与清晰易读相反。

编辑:感谢sawa改进(和调试)答案。

答案 1 :(得分:0)

keys = hash1.keys.drop(1)
  #=> ["2", "3", "4"] 
pairs = hash1.values_at(*keys).zip(hash2.values_at(*keys))
  #=> [["val", ["value"]], ["vall", ["val1", "val2"]], ["", [""]]] 
pairs.all? { |v1,v2| v1.empty? ^ v2.uniq != [""] }
  #=> true 

你当然可以链接最后两个表达式。