【发布时间】:2013-12-04 15:26:18
【问题描述】:
clojure 中是否有一个函数(给定一个谓词和一个集合), 选择满足给定谓词的第一项并停止迭代?
例如:
(select-first #(> % 10) (range))
=> 11
如果没有,也许有人可以提示我一个惯用的实现
【问题讨论】:
标签: clojure
clojure 中是否有一个函数(给定一个谓词和一个集合), 选择满足给定谓词的第一项并停止迭代?
例如:
(select-first #(> % 10) (range))
=> 11
如果没有,也许有人可以提示我一个惯用的实现
【问题讨论】:
标签: clojure
有多种可能性。
some
some 返回其谓词返回的第一个非零值。
(some #(when (> % 10) %) (range)) ;; => 11
filter + first
filter 保留与谓词匹配的那些元素,first 检索其中的第一个。
(first (filter #(> % 10) (range))) ;; => 11
remove + first
如果您想找到第一个不与您的谓词匹配的元素,remove 是您的朋友:
(first (remove #(<= % 10) (range))) ;; => 11
或者some:
(some #(when-not (<= % 10) %) (range)) ;; => 11
所以,我猜就是这样。
【讨论】:
(first (filter ...)) 更严格(而且更快,因为过滤器返回一个惰性序列),因为使用some 是模棱两可的——考虑(some #(when (nil? %) %)。使用 some 会找到第一个 non-nil 元素。
some 来查找nil 元素,您将遍历整个序列(因此可能永远不会终止) - 在其他情况下它只会实现尽可能地延迟序列。但是请注意,我对some 的描述已经包含您强调的 non-nil 部分。 :)
先使用过滤器
user=> (->> (range) (filter #(> % 10)) first)
11
user=> (first (filter #(> % 10) (range)))
11
【讨论】: