31

Clojureで2つのリスト(またはシーケンス)をマージ(または結合を取得)する慣用的な方法は何ですか?

(merge l1 l2)

解決策ではないようです:

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

5 に答える 5

29

andihのソリューションはうまく機能すると思います。ここに別の方法があります。とを使用concatdistinctます。

user> (distinct (concat '(1 2 3) '(2 3 4)))
=> (1 2 3 4)
于 2012-09-30T06:11:45.513 に答える
15

ソートされていない別個のデータ (セット) が必要な場合は、ベクトルやリストではなく、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て、ベクトル マージ アルゴリズムとしてより最適化されたものを使用することを検討してください。into を使用して concat が実装されていない理由がわかりません (または、さらに良いことに、concat が存在するのはなぜですか?ところで、into は concat よりも大幅に高速ですが、conj よりもはるかに遅いです。Bagwell の RRB ツリーは、両方の Clojure と互換性があります)と Scala はこの問題を解決しますが、Clojure にはまだ実装されていません)。

Omri の非セット ソリューションを 'into' の観点から言い換えると、次のようになります。

(distinct (into [1 2 3] [3 4 5]))
=> (1 2 3 4 5)
于 2012-09-30T21:26:35.427 に答える
14

2 つのリストの和集合を取得する 1 つの方法は、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)
于 2012-09-30T04:01:00.707 に答える
2

1 つのオプションはflattenです。

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

注意すべきことの 1 つは、深くネストされたコレクションをフラット化することです。

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

しかし、マップではうまく機能します:

(flatten [[{} {} {}] [{} {} {}]]) ;; => ({} {} {} {} {} {})
于 2017-03-28T09:45:16.830 に答える