在 Clojure 中测试列表是否包含特定值 [英] Test whether a list contains a specific value in Clojure
问题描述
在 Clojure 中测试列表是否包含给定值的最佳方法是什么?
What is the best way to test whether a list contains a given value in Clojure?
特别是,contains?
的行为目前让我很困惑:
In particular, the behaviour of contains?
is currently confusing me:
(contains? '(100 101 102) 101) => false
我显然可以编写一个简单的函数来遍历列表并测试是否相等,但肯定有一种标准的方法可以做到这一点?
I could obviously write a simple function to traverse the list and test for equality, but there must surely be a standard way to do this?
推荐答案
啊,contains?
...据说是 Clojure 的前五个常见问题解答之一.
Ah, contains?
... supposedly one of the top five FAQs re: Clojure.
它不检查集合是否包含一个值;它检查是否可以使用 get
检索项目,或者换句话说,集合是否包含键.这对于集合(可以被认为不区分键和值)、映射(所以 (contains? {:foo 1} :foo)
是 true
是有意义的>) 和向量(但请注意 (contains? [:foo :bar] 0)
是 true
,因为这里的键是索引,并且有问题的向量确实包含" 索引 0
!).
It does not check whether a collection contains a value; it checks whether an item could be retrieved with get
or, in other words, whether a collection contains a key. This makes sense for sets (which can be thought of as making no distinction between keys and values), maps (so (contains? {:foo 1} :foo)
is true
) and vectors (but note that (contains? [:foo :bar] 0)
is true
, because the keys here are indices and the vector in question does "contain" the index 0
!).
更令人困惑的是,在调用 更新:在 Clojure ≥ 1.5 contains?
没有意义的情况下,它只是返回false
;这就是 (contains? :foo 1)
以及 (contains? '(100 101 102) 101)
中发生的事情.contains?
处理不支持预期关键成员"测试的类型的对象时抛出.
To add to the confusion, in cases where it doesn't make sense to call Update: In Clojure ≥ 1.5 contains?
, it simply return false
; this is what happens in (contains? :foo 1)
and also (contains? '(100 101 102) 101)
.contains?
throws when handed an object of a type that doesn't support the intended "key membership" test.
做您想做的事情的正确方法如下:
The correct way to do what you're trying to do is as follows:
; most of the time this works
(some #{101} '(100 101 102))
在搜索一堆项目中的一个时,您可以使用更大的集合;搜索false
/nil
时,可以使用false?
/nil?
-- 因为(#{x} x)
返回 x
,因此 (#{nil} nil)
是 nil
;当搜索多个项目之一时,其中一些可能是 false
或 nil
,您可以使用
When searching for one of a bunch of items, you can use a larger set; when searching for false
/ nil
, you can use false?
/ nil?
-- because (#{x} x)
returns x
, thus (#{nil} nil)
is nil
; when searching for one of multiple items some of which may be false
or nil
, you can use
(some (zipmap [...the items...] (repeat true)) the-collection)
(请注意,项目可以在任何类型的集合中传递给 zipmap
.)
(Note that the items can be passed to zipmap
in any type of collection.)
这篇关于在 Clojure 中测试列表是否包含特定值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!