测试列表是否在Clojure中包含给定值的最佳方法是什么?
特别是,contains?
的行为当前使我感到困惑:
(contains? '(100 101 102) 101) => false
我显然可以编写一个简单的函数来遍历列表并测试是否相等,但是肯定有一种标准方法可以做到这一点吗?
最佳答案
啊,contains?
...大概是前五名常见问题之一:Clojure。
它不检查集合是否包含值。它检查是否可以使用get
检索项目,或者换句话说,集合是否包含关键字。这对于集合(可以认为在键和值之间没有区别),映射(因此(contains? {:foo 1} :foo)
是true
)和 vector (但要注意,(contains? [:foo :bar] 0)
是true
)是有意义的,因为此处的键是索引,并且所讨论的 vector 确实“包含”索引0
!)。
更令人困惑的是,在没有必要调用contains?
的情况下,只返回false
即可;这就是(contains? :foo 1)
和(contains? '(100 101 102) 101)
中发生的情况。更新:在Clojure中,将不支持预期的“密钥成员身份”测试的类型的对象交给时,会抛出contains?
≥1.5。
要做您想做的正确方法如下:
; 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/