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

时间:2018-08-30 18:24:49

标签: arrays ruby algorithm collections

给出一个仅包含奇数的数组:

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

我想确定是否有nil或更多的nil。我使用的方法是首先使所有事物正确或错误。然后确定是否有更多的真或假值:

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

max方法不想与布尔值配合使用。我该怎么做?

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

4 个答案:

答案 0 :(得分:2)

  

给出一个只有奇数的数组

如果您是说一个数组中始终存在不相等数量的真假值,那么[]首先不是有效输入。

这是解决方法:

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,而不是虚假值(如操作说明中所述):

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

答案 1 :(得分:1)

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

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

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

这可以处理空数组,在这种情况下,它返回false

答案 2 :(得分:1)

这里还有一个:

if array.size > 2*array.compact.size
  # We have more nil than non-nil
end

答案 3 :(得分:0)

假设伪造的值分别为{{ 10 | DividedBy: 2}} nil,而其他所有东西都是真实的(如条件语句那样),则可以将falseObject#itself一起使用。

Array#select