如果要查找是否所有元素都符合条件,从数组开始:
array = [1,2,3,1,5,7]
con = array.each_cons(2).all? { |x,y| x < y }
con # => false
更改数组,使元素都小于下一个:
array = [1,2,3,4,5,7]
con = array.each_cons(2).all? { |x,y| x < y }
con # => true
对于数组元素和散列,许多方法的行为相似,因此基本代码是相同的,它们传递到块中的方式发生了变化。我将哈希减少到最低限度来演示代码:
hash = {"3"=>"3","4"=>"1","5"=>"5"}
con = hash.each_cons(2).all? { |(_, x_value), (_, y_value) | x_value < y_value }
con # => false
将哈希更改为递增:
hash = {"3"=>"3","4"=>"4","5"=>"5"}
con = hash.each_cons(2).all? { |(_, x_value), (_, y_value) | x_value < y_value }
con # => true
使用any? 会以同样的方式工作。如果你想知道有没有>=:
hash = {"3"=>"3","4"=>"1","5"=>"5"}
con = hash.each_cons(2).any? { |(_, x_value), (_, y_value) | y_value >= x_value }
con # => true
或者:
hash = {"3"=>"3","4"=>"4","5"=>"5"}
con = hash.each_cons(2).any? { |(_, x_value), (_, y_value) | x_value >= y_value }
con # => false
我正在通过
创建哈希
stripped = Hash[x.scan(/(\w+): (\w+)/).map { |(first, second)| [first.to_i, second.to_i] }]
然后我将删除空数组
new = stripped.delete_if { |elem| elem.flatten.empty? }
这不是使用scan 的好方法。考虑这些:
'1: 23'.scan(/\d+/) # => ["1", "23"]
'1: 23'.scan(/(\d+)/) # => [["1"], ["23"]]
'1: 23'.scan(/(\d+): (\d+)/) # => [["1", "23"]]
首先,scan 返回一个值数组。在第二个中,它返回一个数组数组,其中每个子数组都是一个元素。在第三个中,它返回一个数组数组,其中每个子数组包含扫描的两个元素。您正在使用第三种形式,这不必要地使之后所做的一切复杂化。
不要使传递给scan 的模式复杂化,而是依靠它在查看字符串时返回多个匹配元素并返回这些元素的数组的能力:
'1: 23'.scan(/\d+/) # => ["1", "23"]
在此基础上构建:
'1: 23'.scan(/\d+/).map(&:to_i) # => [1, 23]
Hash[*'1: 23'.scan(/\d+/).map(&:to_i)] # => {1=>23}
注意Hash[] 中的前导*。那个“splat”告诉 Ruby 将数组爆裂或分解成它的组件。如果它不存在,会发生以下情况:
Hash['1: 23'.scan(/\d+/).map(&:to_i)] # => {} # !> this causes ArgumentError in the next release
最后,如果您不需要哈希元素是整数,这与您在问题中给出的哈希相矛盾,只需从上面的示例中删除 .map(&:to_i)。