更好的序列重复卸妆

Mau*_*vez 3 clojure

我做了这个函数来删除连续的重复项,但我想知道是否有更好或更短的方式来表达它使用distinct或类似的东西.

(defn duplicates
  [s]
  (reduce 
    #(if-not (= (last %1) %2) 
      (conj %1 %2) %1) 
    [] s))
Run Code Online (Sandbox Code Playgroud)

Leo*_*hin 6

clojure-1.7.0-alpha1在名称下有这个函数的正确版本dedupe.

您引用的那个返回其输入序列而没有连续的重复.(几乎可以肯定),nil如果他们开始输入序列,它也会吞下所有连续的值.

#(if-not (= (last %1) %2)
    (conj %1 %2)
    %1)
Run Code Online (Sandbox Code Playgroud)

要减少的lambda说:如果accumulator(%1)的最后一个元素与下一个输入元素(%2)不相等,则将其添加到累加器,否则返回累加器.

因为在累加器为空时(last []),nil它的计算结果永远不会添加nil值.我把这作为练习留给读者:

确保 duplicates返回[nil true nil]输入的预期结果[nil nil true true nil].

注意:使用向量操作时,使用peek性能明显优于last.

编辑(自编辑问题以来):仅distinct返回输入序列的每个值一次.不像set它返回懒惰序列.

写一个更惯用的方式duplicates/ dedupe是A. Webb发表评论的方式(因为它也是懒惰的).否则,修复lambda以正确使用空累加器作为其输入并使用peek而不是last更惯用.

clojure-1.7.0-alpha1您可以使用dedupe传感器进行急切评估,而不是固定lambda ,例如:

(into [] (dedupe) [nil nil true true nil])
-> [nil true nil] 
Run Code Online (Sandbox Code Playgroud)

或者懒惰的评价:

(dedupe [nil nil true true nil])
-> (nil true nil)
Run Code Online (Sandbox Code Playgroud)