Ах, 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
в любой тип коллекции.)