2016-03-03 99 views
0

以下代码比较两个散列:一个以字符串作为值,另一个以数组作为值。如何跳过`zip`中的第一对?

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具有值或反之亦然,这是错误的。

我需要比较来跳过两个哈希中的第一个元素。我会加with_index这样做,但我不知道如何添加它,或者如果它是这种情况下的最佳方式。

+0

也许'hash1.zip(hash2).slice(1 ..- 1)'? – mike

+1

你可以使用[Enumerable#each_with_index](http://ruby-doc.org/core-2.2.0/Enumerable.html#method-i-each_with_index):'hash1.zip(hash2).each_with_index.all? {|((_,fv),(_,lv)),i | i.zero? || fv.empty? ^!lv.all?(&:empty?)}#=> true'。 –

回答

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? 

但这就像是非常相反的清晰。

编辑:感谢萨瓦改善(和调试)的答案。

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 

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