调用包含的惯用方式

调用包含的惯用方式

本文介绍了Clojure:调用包含的惯用方式?在惰性序列上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有一种惯用的方法来确定 LazySeq 是否包含一个元素?从 Clojure 1.5 开始,调用 contains? 会抛出 IllegalArgumentException:

Is there an idiomatic way of determining if a LazySeq contains an element? As of Clojure 1.5 calling contains? throws an IllegalArgumentException:

IllegalArgumentException contains? not supported on type: clojure.lang.LazySeq
clojure.lang.RT.contains (RT.java:724)

在 1.5 之前,据我所知,它总是返回 false.

Before 1.5, as far as I know, it always returned false.

我知道在 LazySeq 上调用 contains? 可能永远不会返回,因为它可以是无限的.但是如果我知道它不是并且不在乎它是否被急切地评估怎么办?

I know that calling contains? on a LazySeq may never return as it can be infinite. But what if I know it isn't and don't care if it is evaluated eagerly?

我想到的是:

(defn lazy-contains? [col key]
  (not (empty? (filter #(= key %) col))))

但是感觉不太对.有没有更好的办法?

But it doesn't feel quite right. Is there a better way?

推荐答案

首先,lazy seqs 在检查成员资格方面效率不高.考虑使用集合而不是惰性序列.

First, lazy seqs are not efficient for checking membership. Consider using a set instead of a lazy seq.

如果一套不切实际,你的解决方案还不错.一些可能的改进:

If a set is impractical, your solution isn't bad. A couple of possible improvements:

  1. 非空"有点别扭.仅使用 seq 就足以获得您的用户可以在 if 中使用的 nil-or-truthy 值.如果您想要 true 或 false,您可以将其包装在布尔值中.

  1. "Not empty" is a bit awkward. Just using seq is enough to get a nil-or-truthy value that your users can use in an if.You can wrap that in boolean if you want true or false.

因为你只关心第一个匹配,所以你可以用 some 代替 filter 和 seq.

Since you only care about the first match, you can use some instead of filter and seq.

写等式谓词的一种方便的方法是使用文字集,如#{key},但如果 key 为 nil,则无论是否找到 nil,都将始终返回 nil.

A convenient way to write an equality predicate is with a literal set, like #{key}, though if key is nil this will always return nil whether nil is found our not.

共同为您提供:

(defn lazy-contains? [col key]
  (some #{key} col))

这篇关于Clojure:调用包含的惯用方式?在惰性序列上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 23:34