2015-10-07 19 views
7

Clojureプログラムでは、人々の名前と電子メールを含むマップで構成される配列があります。Clojure独自の等価性

[ 
    { :name "John" :email "[email protected]" } 
    { :name "Batman" :email "[email protected]" } 
    { :name "John Doe" :email "[email protected]" } 
] 
私はペア対等であることを同じ電子メールを持つ、比較のために、考慮重複したエントリを削除したい

。上記の例では、出力は次のようになります:

[ 
    { :name "John" :email "[email protected]" } 
    { :name "Batman" :email "[email protected]" } 
] 

Clojureでこれを達成する最も良い方法は何ですか?同じものが何を使うのか分かっていることを知る方法はありますか?

ありがとうございました。

答えて

6

これは次のようになります。https://crossclj.info/fun/medley.core/distinct-by.html

リンク内の関数は、すべての値を遅延させて表示したすべての値を格納します。 collの値が既に表示されている場合は追加されません。

これを(distinct-by #(% :email) maps)と呼びます。mapsはpeople-mapsのベクトルです。

+6

ように使用することができる例示的なケースについて

(defn distinct-by [f coll] (let [groups (group-by f coll)] (map #(first (groups %)) (distinct (map f coll))))) 

として実装することができます。電子メールマップ) ' – Alex

9

それを行うにはさらに別の方法は、ちょっとより慣用的な、私は推測する:

(let [items [{ :name "John" :email "[email protected]" } 
      { :name "Batman" :email "[email protected]" } 
      { :name "John Doe" :email "[email protected]" }]] 
    (map first (vals (group-by :email items)))) 

出力:

({:name "John", :email "[email protected]"} 
{:name "Batman", :email "[email protected]"}) 

それがどのように動作するかです:

(group-by :email items)はマップを作るにキーはメールで、値はこのメールのレコードのグループです

{"[email protected]" [{:name "John", :email "[email protected]"} 
        {:name "John Doe", :email "[email protected]"}], 
"[email protected]" [{:name "Batman", :email "[email protected]"}]} 

それから、val(レコードのグループ)をとり、その中から最初のものを選択するだけです。

、別の方法それが等しいレコードとして同じ電子メールですべてのレコードを扱いますので、ソートされた電子メールで設定を作成することです:

(let [items [{ :name "John" :email "[email protected]" } 
      { :name "Batman" :email "[email protected]" } 
      { :name "John Doe" :email "[email protected]" }]] 
    (into (sorted-set-by #(compare (:email %1) (:email %2))) items)) 

出力:

#{{:name "Batman", :email "[email protected]"} 
    {:name "John", :email "[email protected]"}} 

ドン」それらのどれがより慣用的であり、より良い性能を有するかは本当に分かります。しかし、私は最初のものに賭ける。

0

distinct-byが容易このキーワードが機能しているので、より多くの慣用的な呼び出しが(別個-によって `あろう

(distinct-by :email 
      [{:name "John" :email "[email protected]"} 
       {:name "Batman" :email "[email protected]"} 
       {:name "John Doe" :email "[email protected]"}])