2013-04-13 3 views
6

Clojureで私の頭の周りをラッピングしています。私は、状態が変わる可能性のある言語から来ています。たとえば、Pythonでは、辞書を作成し、文字列=>整数のペアを内部に入れて、辞書を歩いて値を増やすことができます。マップ内の値をインクリメントする方法

私はこれを慣用的なClojureでどうしますか?

答えて

1

だけproduce新しいマップとそれを使用する:

(def m {:a 3 :b 4}) 

(apply merge 
    (map (fn [[k v]] {k (inc v) }) m)) 

; {:b 5, :a 4} 
+0

1つの価値はどうですか?だから私が{a:7:b 4}を望むならどうしますか?もし私が整数のマップのマップを持っていて、key1 => subkey1 => integer ++の値をインクリメントしたいのであれば? –

+1

@DavidWilliams(update-in my-map [:b] inc);; => {:a 1、:b 3} –

+0

これは新しいマップを作成します。私はこれが国家をもっと難しくしていると思っている。たとえば、ベイズ分類器を作成するには、マルチレベル構造で常に更新されたものを保持する必要があります。 key1 => subkey1 =>整数。 dosyncとswapのマジックをやる必要がありますか? –

7
(def my-map {:a 1 :b 2}) 
(zipmap (keys my-map) (map inc (vals my-map))) 
;;=> {:b 3, :a 2} 

をキーで一つの値だけを更新するには:

(update-in my-map [:b] inc) ;;=> {:a 1, :b 3} 

のClojure 1.7以来、それはupdateを使用することも可能です。

(update my-map :b inc) 
2

複数の値を更新するには、すでに充填されているアキュムレータを減らし、次のコレクションのすべてのメンバに関数を適用することもできます。

=> (reduce (fn [a k] (update-in a k inc)) {:a 1 :b 2 :c 3 :d 4} [[:a] [:c]]) 
{:a 2, :c 4, :b 2, :d 4} 

ベクトルで囲む必要がキーに注意してください、あなたはまだで、元の更新のようなネストされた構造で複数の更新インを行うことができます。

あなたはそれを一般的な機能を加えた場合、あなたは自動ベクトルでキーを包むために必要とすることなく、単一レベル/キーの更新を可能にする高専?:

(defn multi-update-in 
    [m v f & args] 
     (reduce 
     (fn [acc p] (apply 
         (partial update-in acc (if (coll? p) p (vector p)) f) 
         args)) m v)) 

でそれをテストすることによって、キーの上にベクトルをラップすることができ

=> (multi-update-in {:a 1 :b 2 :c 3 :d 4} [:a :c] inc) 
{:a 2, :c 4, :b 2, :d 4} 

それでも、私は同じアイデアをいじるしてきたので、私が思いついたのネストされたアップデートに

(def people 
    {"keith" {:age 27 :hobby "needlefelting"} 
    "penelope" {:age 39 :hobby "thaiboxing"} 
    "brian" {:age 12 :hobby "rocket science"}}) 

=> (multi-update-in people [["keith" :age] ["brian" :age]] inc) 
    {"keith" {:age 28, :hobby "needlefelting"}, 
    "penelope" {:age 39, :hobby "thaiboxing"}, 
    "brian" {:age 13, :hobby "rocket science"}} 
0

を行うことができる:

(defn remap 
    "returns a function which takes a map as argument 
    and applies f to each value in the map" 
    [f] 
    #(into {} (map (fn [[k v]] [k (f v)]) %))) 

((remap inc) {:foo 1}) 
;=> {:foo 2} 

または

(def inc-vals (remap inc)) 

(inc-vals {:foo 1}) 
;=> {:foo 2} 
関連する問題