Почему все? return true в пустом массиве? - программирование
Подтвердить что ты не робот

Почему все? return true в пустом массиве?

Использование 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?

И если мне нужно, чтобы он возвращал false, как мне изменить метод?

4b9b3361

Ответ 1

В Ruby вы никогда не сможете перебрать пустую коллекцию (массив, хэши и т.д.), поэтому в вашем случае ваш блок никогда не будет выполнен. И если блок никогда не будет выполнен, all? возвращает true (нет условия, чтобы сделать результат ложным).

Прочитайте all? в документацию Ruby.

Вы можете просто достичь своей цели

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

Ответ 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 и насколько редка 2 в ней. Поэтому сначала поставьте array.any?.

Также обратите внимание, что существуют вырожденные случаи, когда это не будет работать, например, если array есть [nil] или [false]. Если такие ситуации могут возникнуть, замените array.any? на array.any? { true }.

Ответ 3

В документации говорится: "Метод возвращает true, если блок никогда не возвращает false или noil". В случае пустого массива блок никогда не выполняется и, следовательно, метод всегда будет возвращать true. Что касается возврата false, вам придется arr.empty?

Ответ 4

В этом массиве нет элемента, который не проходит тест. Я думаю, вам может потребоваться выполнить проверку длины массива.

Ответ 5

Просто пойдите

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

(у которого есть дополнительное преимущество неудачной работы, то есть его можно корректно оценивать, не проверяя весь массив.)

Ответ 6

Так как в массиве нет элемента, который НЕИСПРАВНОСТЬ тестирует, он возвращает true. Поэтому просто используйте somehting, например:

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

Или что-то в этом роде.

Ответ 7

Нули, пустые коллекции, пустые матрицы и т.д. всегда были немного особенными, если не откровенно проблематичными. Греки хорошо знали, почему они не посчитали 0 среди натуральных целых чисел.

Метод all? будет первым, кто спросит вас: "Почему вы звоните мне на пустой массив?" Что вы подразумеваете под "всем?", Когда там ничего нет? Это противоречие. И метод делает короткое размышление и отвечает true по причинам, изложенным в других трех ответах. Помните, что вы ошибаетесь, говоря о "всех элементах" пустого массива для начала.

Ответ 8

Как пишет Амит Кумар Гупта, это стандартная интерпретация универсальной квантификации. Я понятия не имею, почему вы ожидаете, что это будет false. Здесь вы можете видеть, что это должно быть true путем вывода.


Универсальное квантификация эквивалентно объединению, поэтому ( "< = > " означает эквивалент):

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

Обратите внимание, что любое предложение эквивалентно объединению истины и самого себя, поэтому:

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

Если вы уменьшите элементы в наборе до двух, вы получите:

"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 с экзистенциальной квантификацией над пустым множеством.

Ответ 9

Источник всего? метод говорит, что он использует статическую переменную (которая первоначально установлена ​​в true), а затем выполняет операцию И между статическим значением переменной и результатом итерации в конечном итоге возвращает эту статическую переменную.

поскольку массив пуст, Ruby никогда не будет итерации в этом пустом массиве и в результате этого все? метод вернет статическую переменную, для которой установлено значение true.

Ответ 10

Убедитесь, что массив сначала не пуст. Тогда:

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