使用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,我应该如何修改方法?
答案 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}