“Updating” a map/data structure in consecutive function calls in Clojure

爱⌒轻易说出口 提交于 2019-12-24 10:46:37

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!