Ах, contains?якобы один из пяти часто задаваемых вопросов о: Clojure.
Он не проверяет, содержит ли коллекция значение; он проверяет, можно ли получить элемент с помощью getили, другими словами, содержит ли коллекция ключ. Это имеет смысл для множеств (которые можно рассматривать как не делающие различий между ключами и значениями), картами (как (contains? {:foo 1} :foo)есть true) и векторами (но обратите внимание, что (contains? [:foo :bar] 0)это trueпотому, что ключи здесь являются индексами, а рассматриваемый вектор «содержит» индекс 0!)
Чтобы добавить путаницу, в случаях, когда нет смысла звонить contains?, он просто возвращается false; это то, что происходит, (contains? :foo 1) а также (contains? '(100 101 102) 101) . Обновление: в Clojure ≥ 1,5 contains?выдает при передаче объект типа, который не поддерживает предполагаемый тест «членство в ключе».
Правильный способ сделать то, что вы пытаетесь сделать, заключается в следующем:
; most of the time this works
(some #{101} '(100 101 102))
При поиске одного из множества предметов вы можете использовать больший набор; при поиске false/ nil, вы можете использовать false?/ nil?- потому что (#{x} x)возвращает x, таким образом, (#{nil} nil)есть nil; при поиске одного из нескольких элементов, некоторые из которых могут быть falseили nil, вы можете использовать
(some (zipmap [...the items...] (repeat true)) the-collection)
(Обратите внимание, что элементы могут быть переданы zipmapв любой тип коллекции.)