我需要过滤给定的向量,以便输出仅包含那些不是直接邻居的重复元素。
Example : I/P -> [1 1 3 2 2 4 5 5]
O/P -> [3 4]
答案 0 :(得分:8)
(defn isolated [coll]
(->> coll
(partition-by identity)
(remove next)
(map first)))
答案 1 :(得分:6)
这与@amalloy的答案完全相同,但是它使用transducers
而不是线程宏(->>
)。
(defn isolate [coll]
(transduce
(comp
(partition-by identity)
(remove next)
(map first))
conj coll))
它应该更有效,至少在大型馆藏上更是如此。
partition-by identity
分区归为相同元素的子列表。 remove next
删除next
不为零的所有子列表(即,它们具有多个元素)。最后一个map first
占据每个子列表的第一个元素,从而将列表的列表展平为元素列表。
只需分别运行每个步骤,以了解其工作原理。
答案 2 :(得分:4)
使用类似@amitr解决方案的换能器,但是恕我直言,更干净一些:
(def isolate
(comp
(partition-by identity)
(remove next)
cat))
然后可以将其与sequence
,into
一起使用,无论您想要哪种换能器接收功能。
答案 3 :(得分:2)
这几乎是一种蛮力解决方案,因此希望我们能看到一些更令人满意的答案,但要使工作顺利进行……
(defn lonely?
"Return the ith element of v if it doesn't have a matching neighbor"
[i v]
(when (cond
(zero? i) (not= (v 0) (v 1))
(= i (- (count v) 1)) (not= (v i) (v (- i 1)))
:else (and (not= (v i) (v (- i 1)))
(not= (v i) (v (+ i 1)))))
(v i)))
> (def v [1 1 3 2 2 4 5 5])
> (keep #(lonely? % v) (range (count v)))
(3 4)
答案 4 :(得分:2)
(def data-1 [1 1 3 2 2 4 5 5])
(def data-2 [1 1 3 2 2 4 5 5 2 5 5])
(defn reducer [[v p] n]
(cond
(empty? v) [[n] n]
(= (peek v) n) [(pop v) n]
(= n p) [v n]
:else [(conj v n) n]))
(first (reduce reducer [[] nil] data-1))
;[3 4]
(first (reduce reducer [[] nil] data-2))
;[3 4 2]
请注意,此解决方案还涵盖了两个以上相邻值相同的情况,例如:
(def data-3 [1 1 3 2 2 2 4 5 5 2 5 5])
;[3 4 2]
所有艰苦的工作都在功能简化器中进行。
从心理上讲,我总是将reduce
的第一个参数标记为“累加器”,将第二个参数标记为“新值”。
在这种情况下,累加器必须具有两个部分:正在创建的向量和最后看到的数字。 (请注意,如果您只希望重复项成对出现,那么最后看到的数字是不必要的。)
因此,[v p]
是减速器的“累加器”部分-v
是要创建的向量,p
是先前看到的值。 n
参数是“新值”。
这四个条件的解释是:
v
为空,只需用新值创建一个新向量并记录
新的价值。这是必要的,因为偷看空向量
(下一个条件)将导致异常。v
的最后一个值与新值相同,请将其删除并记录
新值。n
)与上一个值(p
)相同,则忽略
它。这种情况使我们能够消除重复的值
几次。答案 5 :(得分:1)
从头开始或多或少地构建它,您可以进行分解以完成许多工作:
component.install
话虽如此,我在这几行中犯了两个错误,而Alan Malloy's answer显然是正确的。
这比@dpassen's neat transducer version快吗?
是的。根据Criterium的说法,它的速度大约是它的三倍:大约500纳秒,而简短示例大约为1.5微秒。
答案 6 :(得分:0)
另一种方法:
(defn remove-consecutive-duplicates [inp]
(let [intm (into [] (partition-by identity inp))]
(reduce (fn [acc n]
(if (= 1 (count n))
(conj acc n)
acc ))
[] intm)))
请注意,重复数据删除无法提供所需的输出。