在 Clojure 中测试列表是否包含特定值 [英] Test whether a list contains a specific value in Clojure

查看:15
本文介绍了在 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!).

更令人困惑的是,在调用contains?没有意义的情况下,它只是返回false;这就是 (contains? :foo 1) 以及 (contains? '(100 101 102) 101) 中发生的事情. 更新:在 Clojure ≥ 1.5 contains? 处理不支持预期关键成员"测试的类型的对象时抛出.

To add to the confusion, in cases where it doesn't make sense to call contains?, it simply return false; this is what happens in (contains? :foo 1) and also (contains? '(100 101 102) 101). Update: In Clojure ≥ 1.5 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;当搜索多个项目之一时,其中一些可能是 falsenil,您可以使用

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆