Clojure 更好的序列重复消除器
我使用此函数来删除连续的重复项,但我想知道是否有更好或更短的方法来使用Clojure 更好的序列重复消除器,clojure,Clojure,我使用此函数来删除连续的重复项,但我想知道是否有更好或更短的方法来使用distinct或类似的东西来表达它 (defn duplicates [s] (reduce #(if-not (= (last %1) %2) (conj %1 %2) %1) [] s)) reduce中的匿名函数将一个元素连接成一个序列(如果它与最后一个元素不同)。你可以这样重写它: (defn maybe-conj [s e] (if (= (last s) e)
distinct
或类似的东西来表达它
(defn duplicates
[s]
(reduce
#(if-not (= (last %1) %2)
(conj %1 %2) %1)
[] s))
reduce中的匿名函数将一个元素连接成一个序列(如果它与最后一个元素不同)。你可以这样重写它:
(defn maybe-conj [s e]
(if (= (last s) e)
s
(conj s e)))
然后您可以将压缩序列重写为:
(defn compress-sequence [s]
(reduce maybe-conj [] s))
这将要做的是遍历序列的每个元素,并且仅当它与当前向量中的最后一个元素不同时才将其附加到初始空向量。输出将是初始序列的向量,删除任何运行。例如:
(压缩序列[1 1 1 1 2 3 4 5 5 5 6 6 6 6 6 7 8 9])
评估为
[1 2 3 4 5 6 5 6 7 8 9]
clojure-1.7.0-alpha1
在名称下有此函数的正确版本
您引用的一个返回其输入序列,没有连续的重复项。(几乎可以肯定)如果输入序列开始,它也会不知不觉地吞下所有连续的nil
值
#(if-not (= (last %1) %2)
(conj %1 %2)
%1)
要减少的lambda表示:如果累加器的最后一个元素(%1
)与下一个输入元素(%2
)不相等,则将其添加到累加器中,否则返回累加器
由于(last[])
的计算结果为nil
,因此当累加器为空时,它将永远不会添加nil
值。我将此作为练习留给读者:
确保重复的返回输入[nil-nil-true-nil]
的预期结果[nil-nil-true-nil]
注意:使用向量操作时,使用peek
的性能明显优于last
EDIT(因为您编辑了问题):distinct
只返回输入序列的每个值一次。与set
不同,它返回惰性序列
A.Webb以注释的形式发布了一种更为惯用的方法来编写副本
/重复数据消除
(因为它也是懒惰的)。否则,将lambda修复为在空累加器作为输入的情况下正确工作,并使用peek
而不是last
将更为惯用
在clojure-1.7.0-alpha1
中,您将使用重复数据消除
传感器进行即时评估,而不是固定lambda。g、 :
(into [] (dedupe) [nil nil true true nil])
-> [nil true nil]
或用于延迟评估:
(dedupe [nil nil true true nil])
-> (nil true nil)
嗯,“我很难理解这个函数做什么”,但是你正确地标记了这个问题^ ^ ^更惯用的方式来表达这个(defn compress[s](map first(partition by identity s))
@A.Webb当第一个元素为nil时,你的实现表现不同。@leograpenthin是,正确:)。要删除所有重复值还是仅删除连续值?按照fn的编写方式,(重复[1 2 1])
返回[1 2 1]
。