测试列表是否在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;在搜索多个项目之一(其中一些可能是falsenil)时,可以使用
(some (zipmap [...the items...] (repeat true)) the-collection)

(请注意,可以在任何类型的集合中将项目传递给zipmap。)

关于data-structures - 测试列表是否在Clojure中包含特定值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3249334/

10-09 15:55
查看更多