小编典典

测试列表是否包含 Clojure 中的特定值

all

在 Clojure 中测试列表是否包含给定值的最佳方法是什么?

特别是,contains?目前的行为让我感到困惑:

(contains? '(100 101 102) 101) => false

我显然可以编写一个简单的函数来遍历列表并测试是否相等,但是肯定有一个标准的方法来做到这一点?


阅读 65

收藏
2022-07-28

共1个答案

小编典典

啊,contains?......据说是前五个常见问题解答之一:Clojure。

它不 检查
集合是否包含值;它检查一个项目是否可以被检索到,get或者换句话说,一个集合是否包含一个键。这对于集合(可以被认为不区分键和值)、映射(所以(contains? {:foo 1} :foo)true)和向量(但请注意,因为这里的键(contains? [:foo :bar] 0)true索引,并且所讨论的向量确实“包含”索引0!)。

更令人困惑的是,在调用没有意义的情况下contains?,它只是简单地返回false;这就是发生在(contains? :foo 1)
and (contains? '(100 101 102) 101)中的事情。
更新:
Clojurecontains?中,当提交不支持预期“关键成员资格”测试的类型的对象时,会抛出 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在任何类型的集合中传递。)

2022-07-28