问题
I want to "update" a map through multiple calls of functions, in Clojure. The idea is expressed as below:
(defn foo1
[a-map]
(assoc a-map :key1 "value1"))
(defn foo2
[a-map]
(assoc a-map :key2 "value2"))
(defn foo3
[a-map]
(assoc a-map :key3 "value3"))
(defn -main
[]
(let [a-map {}]
(do (foo1 a-map)
(foo2 a-map)
(foo3 a-map)
a-map)))
Apparently this piece of code is wrong because the a-map is not updated outside the scope of subroutines. It's written like this simply because it's clearer as compared to my current "correct" implementation. The expected result is:
{:key1 "value1" :key2 "value2" :key3 "value3"}
My question is, what is the best way to fulfil the task in the clojure way.
I have considered nesting a few let expressions where each let can hold the result of the updated a-map. I also considered using a loop-recur structure where the a-map is passed as a binding. But both approaches look untidy.
Any advice would be appreciated.
Cheers
EDIT: Adding a constraint to the question. The functions foo1, foo2, foo3
actually takes more parameters than only the a-map
. And some of these parameters can only be determined by processing the arguments passed to -main
.
回答1:
assoc
returns the updated map so you can chain your calls using the ->
threading macro:
(let [a-map (-> {}
foo1
foo2
foo3)] ...)
or you could use comp
:
(let [a-map ((comp foo3 foo2 foo1) {})]...)
来源:https://stackoverflow.com/questions/29234501/updating-a-map-data-structure-in-consecutive-function-calls-in-clojure