2012-03-15 10 views
26

私は、マップからキーを削除する機能を持っている:マップから複数のキーを削除するにはどうすればよいですか?

(defn remove-key [key map] 
    (into {} 
     (remove (fn [[k v]] (#{key} k)) 
       map))) 

(remove-key :foo {:foo 1 :bar 2 :baz 3}) 

私は複数のキーを使用して、この機能を適用するにはどうすればよいですか?

(remove-keys [:foo :bar] {:foo 1 :bar 2 :baz 3}) 

私はloop ... recurを使用して実装しています。 Clojureでこれを行うもっと慣用的な方法がありますか?

(defn remove-keys [keys map] 
    (loop [keys keys 
     map map] 
    (if (empty? keys) 
     map 
     (recur (rest keys) (remove-key (first keys) map))))) 

答えて

44

を持っている場合、あなたのremove-key関数は標準ライブラリで覆われています機能dissocdissocは一度に複数のキーを削除しますが、キーはリストではなく引数リストに直接指定します。だから、applyを使って "平坦化"することができます。

(apply dissoc {:foo 1, :bar 2, :baz 3} [:foo :bar]) 
==> {:baz 3} 
40

dissocマップから1つ以上のキーを削除します。

(dissoc {:foo 1 :bar 2 :baz 3} :foo :bar) 

か、あなたは、コレクション内のキー

(apply dissoc {:foo 1 :bar 2 :baz 3} [:foo :bar]) 
+0

Clojureには、関数呼び出しのベクトルを "爆発させる"方法がありませんか? ala Pythonの '* list'? – john2x

+5

@ john2x、 'apply'はそれを正確に行います。つまり、 '(f foo bar bazを適用する)'は、Pythonの 'f(foo bar * baz)'に相当します。 –

11

他の人が独自の関数を記述するのではなく、組み込み関数を使用していると述べています。

ただし、これはあくまで一例だったとあなたは標準dissocがなかった場合、その後、あなたが使用できることを行う方法の答えたい場合:あなたは、引数を元に戻す場合は、

(reduce (fn [m k] (remove-key k m)) {:foo 1 :bar 2 :baz 3} [:foo :bar]) 

明らかにそれははるかに簡単に書くことができ、キーを削除するには:https://github.com/boxed/instar

(reduce remove-key {:foo 1 :bar 2 :baz 3} [:foo :bar]) 
1

私はので、私は図書館齢を作成し、それを修正するために、Clojureの中に超迷惑するものと他人のこのタイプを発見しました。

関連する問題