在 Clojure 中合并(或检索联合)两个列表(或序列)的惯用方法是什么?
(merge l1 l2)
似乎不是解决方案:
a=> (merge '(1 2 3) '(2 3 4))
((2 3 4) 1 2 3)
If what you want is actually distinct unsorted data (sets), you should be using Clojure's set data structure instead of vectors or lists. And as andih suggested indirectly, there is a core library for set operations: 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}
If sets are for whatever reason not what you want, then read on. Careful with concat
when you have a significant amount of data in your sequences, and consider using into
which is much better optimized as a vector merging algorithm. I don't know why concat is not implemented using into (or better yet-- why does concat even exist? BTW while into is significantly faster than concat, it is still way way slower than conj. Bagwell's RRB trees, compatible with both Clojure and Scala, will solve this problem, but are not yet implemented for Clojure).
To rephrase Omri's non-set solution in terms of 'into':
(distinct (into [1 2 3] [3 4 5]))
=> (1 2 3 4 5)
获得两个列表并集的一种方法是使用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)
如果您不介意重复,可以尝试concat:
(concat '(1 2 3 ) '(4 5 6 1) '(2 3))
;;==> (1 2 3 4 5 6 1 2 3)
一种选择是flatten:
(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)
但适用于地图:
(flatten [[{} {} {}] [{} {} {}]]) ;; => ({} {} {} {} {} {})