在 Clojure 中测试列表是否包含给定值的最佳方法是什么?
特别是,contains?
的行为目前让我感到困惑:
(contains? '(100 101 102) 101) => false
我显然可以编写一个简单的函数来遍历列表并测试相等性,但肯定有一个标准的方法来做到这一点?
最佳答案
啊,包含?
...据说是有关 Clojure 的五个常见问题解答之一。
它不检查集合是否包含值;它检查是否可以使用 get
检索项目,或者换句话说,集合是否包含键。这对于集合(可以认为不区分键和值)、映射(因此 (contains? {:foo 1} :foo)
是 true
)和向量(但请注意 (contains? [:foo :bar] 0)
为 true
,因为这里的键是索引,并且所讨论的向量确实“包含“索引0
!)。
更令人困惑的是,在调用 更新: 在 Clojure ≥ 1.5 contains?
没有意义的情况下,它只是返回 false
;这就是 (contains? :foo 1)
以及 (contains? '(100 101 102) 101)
中发生的情况。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
。)
关于data-structures - 在 Clojure 中测试列表是否包含特定值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3249334/