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