Каков правильный «способ clojure», чтобы проверить, не является ли коллекция не пустой - PullRequest
23 голосов
/ 25 июня 2010

Я хочу написать функцию, которая бы возвращала логическое значение true, если заданная коллекция не пуста, и false в противном случае.

Я мог бы сделать

defn ..
(boolean (seq coll))

или

defn ..
(not (empty? coll))

Поскольку я новичок в clojure, я изначально был склонен идти с # 2 (более читабельным), но ссылка на API clojure для empty? явно говорит, что используйте идиому (seq coll) вместо (not (empty? coll)), возможно, чтобыИзбегайте двойного отрицания.

Я хочу знать, что такое закрытый способ проверить, не является ли коллекция непустой, и вернуть логическое значение true / false.

Ответы [ 3 ]

26 голосов
/ 19 июля 2011

Согласно Радости Clojure, ноль ударов с seq идиоматичны:

(defn print-seq [s]
  (when (seq s)
    (prn (first s))
    (recur (rest s))))

"... использование seq в качестве условия завершения является идиоматическим способом проверки того, является ли последовательность пустой. Если мы проверили [в приведенном выше примере] просто s вместо (seq s), то завершающее условие не возникнет даже для пустых коллекций ... "

12 голосов
/ 25 июня 2010

Отрывок из упомянутой вами строки документации empty?, в частности, означает, что такая функция nonempty? никогда не должна быть необходимой или даже особенно полезной, потому что seq всегда может заменить ее в булевых контекстах, которые в чистом коде Clojure это может.

Если вы все же чувствуете необходимость написать такую ​​функцию, я скажу, что мне больше нравится первый подход. В любом случае empty? построен на seq, так что нельзя не назвать его; простое приведение результата к логическому результату кажется чище, чем две поездки через not. Другие варианты см., Например, nil?, false? (я все еще предпочитаю актерский состав).

Кстати, почему ты хочешь написать это ...? Возможно, для вызова метода Java с аргументом boolean? В этом случае, я думаю, актеры хорошо выразят намерение.

Обновление: Пример, иллюстрирующий последнюю точку:

  1. Простой класс Java:

    public class Foo {
      public static boolean foo(boolean arg) {
        return !arg;
      }
    }
    
  2. Какой-то код клиента Clojure:

    (Foo/foo nil)
    ; => NullPointerException
    (Foo/foo (boolean nil))
    ; => true
    
4 голосов
/ 25 июня 2010

В дополнение к отличному ответу Михала Марчика я укажу, что есть специальная непустая функция:

http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/not-empty

но он не делает именно то, что вы просите. (Хотя это будет работать в большинстве ситуаций).

Not-empty возвращает nil, если коллекция пуста, и саму коллекцию, если коллекция не пуста. Для тестов предикатов это будет хорошо работать. Если вам действительно нужны значения true и false, тогда (не (пусто? X)) вы ищете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...