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

时间:2013-05-21 05:27:49

标签: ruby

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

我可以使用例如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,我应该如何修改方法?

10 个答案:

答案 0 :(得分:25)

这是vacuous truth。它是通用量化的标准解释,即

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

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

要使测试要求数组非空,只需执行

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

请注意,无论数组有多大,array.any?都很快,而array.all? { |x| x == 2 }可能会很慢,具体取决于array的大小以及2的罕见程度。所以先放array.any?

另请注意,如果array[nil][false],则会出现无效的退化情况。如果出现此类情况,请将array.any?替换为array.any? { true }

答案 1 :(得分:8)

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

了解the Ruby documentation中的all?

您可以通过

简单地实现目标
  !array.empty? && array.all? { |value| value == 2 }

答案 2 :(得分:5)

文档说:“如果块永远不会返回false或nil,则该方法返回true。” 在空数组的情况下,块永远不会执行,因此该方法将始终返回true。就回归false而言,您必须arr.empty?

答案 3 :(得分:4)

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

答案 4 :(得分:1)

快去

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

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

答案 5 :(得分:0)

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

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

或类似的东西。

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

正如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在空集上存在量化。

答案 8 :(得分:0)

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

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

答案 9 :(得分:0)

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

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