代码之家  ›  专栏  ›  技术社区  ›  Daniel Viglione

检查数组是否包含比其他值更多的nils

  •  -2
  • Daniel Viglione  · 技术社区  · 8 年前

    给定一个只有奇数的数组:

    [1,nil,nil]
    [1,nil,Module,nil,2]
    [1,Class.new,nil]
    

    我想确定是否有零或更多的非零。我用的方法是先把所有的事情都说对或错。然后确定是否有更多的真值或假值:

    [ 1,nil,nil,nil,2,3].collect {|val| !!!val }.max
    #=> ArgumentError: comparison of TrueClass with false failed
    

    max方法不想处理布尔函数。我怎样才能做到这一点?

    现在,这可能不是确定是否有更多的零或非零的最佳方法,但这是我使用的方法。

    4 回复  |  直到 8 年前
        1
  •  2
  •   Andrey Deineko    8 年前

    给定一个只有奇数的数组

    [] 不是有效的输入。

    def truthy?(array)
      falsey, truthy = array.partition(&:!)
    
      truthy.size > falsey.size
    end
    

    如果您喜欢,可以选择oneliner:

    def truthy?(array)
      array.partition(&:!).max_by(&:size).any?
    end
    

    规格:

    truthy?([1,nil,nil])          #=> false
    truthy?([1,nil,nil,nil,2])    #=> false
    truthy?([1,4,nil])            #=> true
    truthy?([1,nil,nil])          #=> false
    truthy?([1,nil,Module,nil,2]) #=> true
    truthy?([1,Class.new,nil])    #=> true
    


    如果你真的打算只计算 nil s、 非虚假值(如OP中所述):

    def more_nils?(array)
      array.partition(&:nil?).max_by(&:size).none?
    end
    

    规格:

    more_nils?([1,nil,nil])          #=> true
    more_nils?([1,nil,nil,nil,2])    #=> true
    more_nils?([1,4,nil])            #=> false
    more_nils?([1,nil,nil])          #=> true
    more_nils?([1,nil,Module,nil,2]) #=> false
    more_nils?([1,Class.new,nil])    #=> false
    

    它使用 Object#nil? 方法。

    灵感来自 @pjs's answer :

    array.sum { |el| el.nil? ? -1 : 1 }.negative?
    

    更简单(来自@SagarPandya的评论)

    array.count(nil) > array.compact.count
    
        2
  •  1
  •   pjs    8 年前

    一个相当简单的解决方案是:

    def truthy?(ary)
      ary.map { |bool| bool ? 1 : -1 }.sum > 0
    end
    

    根据条目的真实性和总和,将条目映射到+/-1,然后查看总和是正还是负。

    它可以处理空数组,返回 false

        3
  •  1
  •   user1934428    8 年前

    这里还有一个:

    if array.size > 2*array.compact.size
      # We have more nil than non-nil
    end
    
        4
  •  0
  •   Bartosz Pietraszko    8 年前

    假设falsy值为 nil false ,其他的一切都是真实的(就像条件语句一样),您可以利用 Object#itself Array#select .

    irb(main):013:0> ary = [1,nil,nil,false,2]
    => [1, nil, nil, false, 2]
    irb(main):014:0> ary.select(&:itself).length
    => 2
    irb(main):015:0> ary.reject(&:itself).length
    => 3