Clojure库中是否存在用于过滤集合和返回一对集合的函数,其中一个集合包含谓词返回true的项目,另一个集合包含谓词返回false的项目?
例如:
(let [[yays nays] (some-fn pred coll)] ... )
或多或少,我正在寻找一种基于谓词排序的方法,而不是扔掉(比如filter
或remove
)。
(注意:我知道解决方案是分别在集合上调用filter
和remove
;我只想知道是否有内置函数可以更有效地完成此任务。
(编辑:seq-utils/separate
不符合更高效的条件。它会为每个项目评估谓词两次。)
答案 0 :(得分:3)
答案 1 :(得分:1)
如果你想获得最佳性能,你可以使用loop / recur来完成这项工作,例如:
(defn separate-by [pred coll]
(loop [yays nil
nays nil
s (seq coll)]
(if s
(let [item (first s)
test (pred item)]
(if test
(recur (conj yays item) nays (next s))
(recur yays (conj nays item) (next s))))
{:yays yays :nays nays})))
这个效率最高的原因是循环/重复使您能够迭代地构建两个输出列表而无需任何额外的内存分配(例如,如果您重复更新地图会发生这种情况)或参考开销(如果你使用两个原子来积累结果。)