Chapter 5, Exercise 3 in Clojure for the Brave and True requires:
Implement the assoc-in function. Hint: use the
assoc
function and define its parameters as[m [k & ks] v]
.
Although I have found this solution (see lines 39-54), I wondered if there was a different way of doing it. When working on the previous exercise, I found this very clear answer by jbm on implementing the comp function to be very helpful.
I've been trying to reduce a partial assoc over a conjoined list of keys and apply the returned function to the final value:
(defn my-part-assoc [m k]
(partial assoc m k))
((reduce my-part-assoc {} [:one :two :three]) "val")
Needless to say, this doesn't work. I am new to Clojure and functional programming and fear my very basic understanding of reduce is leading me down the wrong path. Please can someone provide a more concise answer?
Shortly after posting, I found this , which gets the following definition from the Clojure GitHub repo :
(defn assoc-in
;; metadata elided
[m [k & ks] v]
(if ks
(assoc m k (assoc-in (get m k) ks v))
(assoc m k v)))
Here is a solution that doesn't use "assoc-in" which seems to be a requirement:
(defn my-assoc-in
[m [k & ks] v]
(if (= (count ks) 0)
(assoc m k v)
(let [ordered-ks (reverse ks)
first-m (get-in m (butlast (cons k ks)))]
(assoc m k (reduce
(fn [curr-m next-k] (assoc {} next-k curr-m))
(assoc first-m (first ordered-ks) v)
(rest ordered-ks))))))```
I think Ooberdan's idea works in case of:
(defn my-as-in
"assoc val in nested map with nested key seq"
[mp [ky & kysq] val]
(if kysq
(assoc mp ky (my-as-in (get mp ky) kysq val))
(assoc mp ky val)))
(my-as-in {} [:is :this :hello] 1)
gives {:is {:this {:hello 1}}}
same as assoc-in
...
Seems neat and idiomatic Clojure and it showed me the way after I got lost in reduce
or multi arity type solutions.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.