【问题标题】:Library function for sorting based on a predicate基于谓词排序的库函数
【发布时间】:2012-01-07 22:09:07
【问题描述】:

Clojure 库中是否存在用于过滤集合并返回一对集合的函数,其中一个包含谓词返回 true 的项目,另一个包含谓词返回 false 的项目?

例如:

(let [[yays nays] (some-fn pred coll)] ... )

或多或少,我正在寻找一种基于谓词进行排序的方法,而不是扔掉(比如filterremove)。

(注意:我知道一个解决方案是在集合上分别调用filterremove;我只是想知道是否有一个内置函数可以更有效地完成此操作。

(编辑:seq-utils/separate 效率不高。它为每个项目评估谓词两次。)

【问题讨论】:

    标签: collections clojure


    【解决方案1】:

    【讨论】:

      【解决方案2】:

      如果您想要获得最佳性能,您可以使用循环/递归来做到这一点,例如:

      (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})))
      

      这样做最有效的原因是循环/递归使您能够迭代地构建两个输出列表,而无需任何额外的内存分配(例如,如果您重复更新地图就会发生这种情况)或引用开销(如果您使用了两个原子来累积结果)。

      【讨论】:

      • 这会颠倒输入序列的顺序,这通常是一个意想不到的副作用。从[] 开始可能比nil 更好。但这肯定是最快的方法:我根本没有看到任何低效率。不过请注意,@scrapdog,这个解决方案不是懒惰的(我的也不是)。任何既惰性又不可变的解决方案必然会遍历序列两次。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-28
      • 2016-11-10
      • 2018-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-23
      相关资源
      最近更新 更多