Why does .all? return true on an empty array?

2020-02-10 01:56发布

Using Ruby I want to evaluate all items in an array, and return true if they all pass a conditional test.

I can do this using e.g. array.all? { |value| value == 2 }

So:

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

Great!

But, why does an empty array pass this test?

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

Shouldn't this return false?

And if I need it to return false, how should I modify the method?

标签: ruby
10条回答
在下西门庆
2楼-- · 2020-02-10 02:16

In Ruby you can never loop over an empty collection (array, hashes, etc.), so in your case your block never gets executed. And if the block never gets executed, all? returns true (there is no condition to make the result false).

Read about all? in the Ruby documentation.

You can simply achieve your goal by

  !array.empty? && array.all? { |value| value == 2 }
查看更多
叼着烟拽天下
3楼-- · 2020-02-10 02:16

Just go

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

(Which has the added advantage of failing fast—that is, it can be evaluated properly without having to scan the whole array.)

查看更多
够拽才男人
4楼-- · 2020-02-10 02:24

Make sure the array is not empty first. Then:

array.compact.present? && array.all? {|x| x != 2}
查看更多
来,给爷笑一个
5楼-- · 2020-02-10 02:25

Zeroes, empty collections, empty matrices and such have always been a bit special, if not outright problematic. Greeks knew well why they didn't count 0 among natural integers.

Method all? would be the first to ask you "why are you calling me on an empty array?" What do you mean by "all?", when there is nothing in there? That's a contradiction. And the method does short thinking, and answers true for the reasons outlined in the other three answers. Remember, you are at fault for talking about "all elements" of an empty array to begin with.

查看更多
登录 后发表回答