如何在clojure中合并两个序列?

时间:2012-09-30 03:15:16

标签: clojure sequences

在Clojure中合并(或检索联合)两个列表(或序列)的惯用方法是什么?

(merge l1 l2)

似乎不是解决方案:

a=> (merge '(1 2 3) '(2 3 4))
((2 3 4) 1 2 3)

5 个答案:

答案 0 :(得分:28)

我认为andih的解决方案效果很好。这是另一种方式,因为嘿,为什么不呢。它使用concatdistinct

user> (distinct (concat '(1 2 3) '(2 3 4)))
=> (1 2 3 4)

答案 1 :(得分:14)

获得两个列表联合的一种方法是使用union

Clojure> (into #{} (clojure.set/union '(1,2,3) '(3,4,5)))
#{1 2 3 4 5}

或者如果你想获得一个清单

(into '() (into #{} (clojure.set/union '(1,2,3) '(3,4,5))))
(5 4 3 2 1)

答案 2 :(得分:14)

如果你想要的实际上是不同的未排序数据(集合),你应该使用Clojure的集合数据结构而不是向量或列表。正如andih间接建议的那样,集合操作有一个核心库:http://clojure.github.com/clojure/clojure.set-api.html

(require '[clojure.set :refer [union]])

(union #{1 2 3} #{3 4 5})
=> #{1 2 3 4 5}

如果套装出于任何原因而不是您想要的,请继续阅读。当序列中包含大量数据时,请小心concat,并考虑使用into作为向量合并算法进行优化。我不知道为什么concat没有使用into实现(或者更好 - 为什么concat甚至存在?BTW虽然明显快于concat,但它仍然比conj.Bagwell的RRB树慢,与Clojure兼容和Scala,将解决这个问题,但尚未实现Clojure)。

用'into'来改写Omri的非设定解决方案:

(distinct (into [1 2 3] [3 4 5]))
=> (1 2 3 4 5)

答案 3 :(得分:7)

如果您不介意重复,可以尝试concat

(concat '(1 2 3 ) '(4 5 6 1) '(2 3)) 
;;==> (1 2 3 4 5 6 1 2 3) 

答案 4 :(得分:2)

一个选项是flatten

$Array = json_decode($jsonArray,true);

要注意的一件事是它会压缩深层嵌套的集合:

(def colls '((1 2 3) (2 3 4)))
(flatten colls) ;; => (1 2 3 2 3 4)
(distinct (flatten colls)) ;; => (1 2 3 4)

但适用于地图:

(flatten [[1 2 [3 4 5]] [1 [2 [3 4]]]]) ;; => (1 2 3 4 5 1 2 3 4)