为什么.all? 在空数组上返回true?

使用Ruby我想评估数组中的所有项,如果它们都通过了条件测试,则返回true。

我可以使用例如array.all? { |value| value == 2 }来做到这array.all? { |value| value == 2 } array.all? { |value| value == 2 }

所以:

 > array=[2,2] > array.all? { |value| value == 2 } => true > array=[2,3] > array.all? { |value| value == 2 } => false 

大!

但是,为什么一个空数组通过了这个测试呢?

 > array=[] > array.all? { |value| value == 2 } => true 

这不应该是假的吗?

如果我需要它返回false,我应该如何修改方法?

在Ruby中,你永远不能遍历空集合(数组,散列等),所以在你的情况下你的块永远不会被执行。 如果块永远不会被执行, all? 返回true(没有条件使结果为false)。

了解all? 在Ruby文档中 。

你可以简单地实现你的目标

  !array.empty? && array.all? { |value| value == 2 } 

这是一个空洞的事实 。 它是通用量化的标准解释,即a

 collection.all? { |x| some_predicate(x) } 

在一个空的collection ,但众所周知,当他们第一次在正式场合看到它时,会让人们反直觉。 考虑为什么这是首选语义的一个好方法是考虑如何实现all?

要使测试要求数组非空,只需这样做

 array.any? && array.all? { |x| x == 2 } 

注意array.any? 无论数组array.all? { |x| x == 2 } ,而array.all? { |x| x == 2 } array.all? { |x| x == 2 } array.all? { |x| x == 2 }可能很慢,具体取决于array大小和2中的稀疏程度。 所以把array.any?所以array.any? 第一。

还要注意,有一些退化的情况,这将无法工作,例如,如果array[nil][false] 。 如果这样的情况可能会出现,请替换array.any?array.any? { true } array.any? { true }

文档说:“ 如果块永远不返回false或nil,则该方法返回true。 ”在空数组的情况下,块永远不会执行,因此该方法将始终返回true 。 至于返回false ,你需要arr.empty?

该数组中没有未通过测试的项目。 我想你可能需要对数组长度进行测试。

去吧

 !(array.empty? || array.any? {|x| x != 2}) 

(它具有快速失败的附加优势 – 也就是说,无需扫描整个arrays即可正确评估它。)

由于数组中没有FAILS测试的项,因此返回true。 所以只需使用像:

 array.size > 0 and array.all? { |value| value == 2} 

或类似的东西。

零,空集合,空矩阵等等总是有点特殊,如果不是彻头彻尾的问题。 希腊人很清楚为什么他们在自然整数中不算0。

方法all? 会是第一个问为什么叫我空阵?” 什么是“全部?”,什么都没有? 这是一个矛盾。 并且该方法做了简短的思考,并且由于其他三个答案中概述的原因而回答true 。 请记住,你开始讨论空数组的“所有元素”是错误的。

正如Amit Kumar Gupta所写,这是对通用量化的标准解释。 我不知道为什么你认为它是false 。 在这里,您可以通过推理看到它应该是true的。


通用量化等同于连词,因此(“<=>”表示等效):

 "for all x in [a, b, c], P(x)" <=> "P(a) and P(b) and P(c)" 

请注意,任何命题都等同于true和self的结合,因此:

 "for all x in [a, b, c], P(x)" <=> "true and P(a) and P(b) and P(c)" 

如果将集合中的元素减少为2,则得到:

 "for all x in [a, b], P(x)" <=> "true and P(a) and P(b)" 

并进一步到一个元素:

 "for all x in [a], P(x)" <=> "true and P(a)" 

现在,空集怎么了? 自然,

 "for all x in [], P(x)" <=> "true" 

通过注意到存在量化等同于析取,您还可以看到,对于空集合,您应该对存在量化进行false

所有的来源? 方法说它使用静态变量(最初设置为true)然后在静态变量值和迭代结果之间执行AND操作,最后返回此静态变量作为结果。

因为数组是空的ruby永远不会在这个空数组上迭代,并且由于这一切? 方法将返回设置为true的静态变量。

确保数组先不为空。 然后:

 array.compact.present? && array.all? {|x| x != 2}