ClojureDocs

Nav

Namespaces

assoc-in

clojure.core

Available since 1.0 (source)
  • (assoc-in m [k & ks] v)
Associates a value in a nested associative structure, where ks is a
sequence of keys and v is the new value and returns a new nested structure.
If any levels do not exist, hash-maps will be created.
9 Examples
(def users [{:name "James" :age 26}  {:name "John" :age 43}])

;; update the age of the second (index 1) user 
(assoc-in users [1 :age] 44)
;;=> [{:name "James", :age 26} {:name "John", :age 44}]

;; insert the password of the second (index 1) user
(assoc-in users [1 :password] "nhoJ")
;;=> [{:name "James", :age 26} {:password "nhoJ", :name "John", :age 43}]

;; create a third (index 2) user
;; Also (assoc m 2 {...}) or (conj m {...})
(assoc-in users [2] {:name "Jack" :age 19})  
;;=> [{:name "James", :age 26} {:name "John", :age 43} {:name "Jack", :age 19}]

;; From http://clojure-examples.appspot.com/clojure.core/assoc-in
;; can be used to update a mutable item.
(def ppl (atom {"persons" {"joe" {:age 1}}}))
(swap! ppl assoc-in ["persons" "bob"] {:age 2})

@ppl
;;=> {"persons" {"joe" {:age 1}, "bob" {:age 2}}}
;; be careful with that empty path sequence, it's seldom what you want
(assoc-in {} [] {:k :v})
;;=> {nil {:k :v}}

;; In general, you find that for a non-empty path
;;   (get-in (assoc-in m path v) path) 
;; is equal to v.
;; Surprisingly this does not hold true in case of an empty path.
;; another example of updating a mutable item.
;; this time the first key is to a map and the second to a vector.
(def foo (atom {:users [{:a "a"} {:b "b"}]}))
(swap! foo assoc-in [:users 2] {:c "c"})
;;=> {:users [{:a "a"} {:b "b"} {:c "c"}]}

;; assoc-in into a nested map structure
(def foo {:user {:bar "baz"}})
(assoc-in foo [:user :id] "some-id")
;;=> {:user {:bar "baz", :id "some-id"}}
(assoc-in {} [:cookie :monster :vocals] "Finntroll")
; => {:cookie {:monster {:vocals "Finntroll"}}}

(get-in {:cookie {:monster {:vocals "Finntroll"}}} [:cookie :monster])
; => {:vocals "Finntroll"}

(assoc-in {} [1 :connections 4] 2)
; => {1 {:connections {4 2}}}

;; from http://www.braveclojure.com/functional-programming/
;; assoc-in can be used on vectors too

(def row 0)
(def col 0)

(assoc-in [[1 1 1]
           [1 1 1]
           [1 1 1]] [row col] 0)
; => [[0 1 1][1 1 1][1 1 1]]

(get-in [[0 1 1]
         [1 1 1]
         [1 1 1]] [row col])
; => 0
; Playing around with assoc-in

(assoc-in {:person {:name "Mike"}} [:person :name] "Violet")
; => {:person {:name "Violet"}}

(assoc-in {:person {:name "Mike"}} [:person] "Violet")
; => {:person "Violet"}

(assoc-in [{:person {:name "Mike"}}] [0 :person :name] "Violet")
; => [{:person {:name "Violet"}}]

(assoc-in [{:person {:name ["Mike"]}}] [0 :person :name 1] "Smith")
; => [{:person {:name ["Mike" "Smith"]}}]

(assoc-in [{:person {:name ["Mike"]}}] [0 :person :name 2] "Smith")
; => IndexOutOfBoundsException
;; Note that, unlike `assoc`, `assoc-in` cannot be used with multiple values.

(def my-map {})

;; This works
(assoc my-map :a 1
              :b 2
              :c 3)
; => {:a 1, :b 2, :c 3}

;; This doesn’t
(assoc-in my-map [:a :aa] 1
                 [:b :bb] 2
                 [:c :cc] 3)
; ArityException Wrong number of args (7) passed to: core/assoc-in

;; This works
(-> my-map
    (assoc-in [:a :aa] 1)
    (assoc-in [:b :bb] 2)
    (assoc-in [:c :cc] 3))
See Also

assoc[iate]. When applied to a map, returns a new map of the same (hashed/sorted) type, that con...

Added by alimoeeny

'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a fun...

Added by zk

Returns the value in a nested associative structure, where ks is a sequence of keys. Returns nil i...

Added by jks

Returns true if coll implements Associative

Added by xmo-odoo
1 Note
    By , created 3.0 years ago, updated 3.0 years ago

    Unlike assoc, you can only do one kv at a time:

    ;; Allowed
    (assoc {} :a "a" :b "b" :c "c")
    ;; Not allowed:
    (assoc-in {} [:a :b] "cya" [:a :d :e] "f" [:b :g] "wow")