nan*_*sen 10 clojure lazy-sequences
是否有一种惯用的方法来确定LazySeq是否包含元素?从Clojure 1.5开始,调用contains?抛出IllegalArgumentException:
IllegalArgumentException contains? not supported on type: clojure.lang.LazySeq
clojure.lang.RT.contains (RT.java:724)
Run Code Online (Sandbox Code Playgroud)
在1.5之前,据我所知,它总是返回false.
我知道调用contains?LazySeq可能永远不会返回,因为它可能是无限的.但是如果我知道它不是并且不关心它是否被热切评估呢?
我想出的是:
(defn lazy-contains? [col key]
(not (empty? (filter #(= key %) col))))
Run Code Online (Sandbox Code Playgroud)
但它感觉不太对劲.有没有更好的办法?
Cho*_*ser 11
首先,懒惰的seqs不能有效地检查会员资格.考虑使用集合而不是懒惰的seq.
如果一套是不切实际的,那么你的解决方案也不错.一些可能的改进:
"不空"有点尴尬.只使用seq就足以获得用户可以在if中使用的nil-or-truthy值.如果你想要true或false,你可以用布尔值包装它.
由于您只关心第一场比赛,您可以使用一些而不是过滤器和seq.
编写等式谓词的一种简便方法是使用文字集,如#{key},但如果key为nil,则无论nil是否为n,这将始终返回nil.
一起给你:
(defn lazy-contains? [col key]
(some #{key} col))
Run Code Online (Sandbox Code Playgroud)
如果您在示例中使用some而不是,filter一旦找到值,您将立即获得返回,而不是强制评估整个序列。
(defn lazy-contains? [coll key]
(boolean (some #(= % key) coll)))
Run Code Online (Sandbox Code Playgroud)
编辑:如果您不将结果强制为布尔值,请注意,如果未找到密钥,您将获得nil而false不是。