Clojure中的渐进联想

Hen*_*gon 3 clojure

我遇到了一个我今天需要的东西,我希望逐步将地图中的条目关联起来,每个条目都基于前一个的结果.这是我做的:

(defn -Y [v k f] (assoc v k (f v)))

(defn build-map [a-map]
 (-> a-map
  (-Y :x #(reduce + (:values %) )  )
  (-Y :y #(/ (:x %) 100) )
  (-Y :z #(* (:y %) 10000000) )
 )
)
(build-map {:values (range 8)})
Run Code Online (Sandbox Code Playgroud)

我欢迎你的想法a)这是一件好事吗?b)有没有现成的方法可以做到我没见过?(我不太了解API)

Chr*_*erg 10

我认为Ankur的答案是对原始设计的一个很好的改进.

我只想提一下,并不总是需要使事情过于复杂.如果你计算同一函数中的所有其他映射条目,我认为这种简单的方法更具可读性:

(defn build-map [a-map]
  (let [x (reduce + (:values a-map))
        y (/ x 100)
        z (* y 10000000)]
    (merge a-map {:x x :y y :z z})))
Run Code Online (Sandbox Code Playgroud)


Ank*_*kur 7

所以你得到了一张经过一些转换的地图,你最终得到了一张最终的地图.你的实现对我来说很好,除了-Y没有做太多事情,它可能不需要作为一个单独的功能.

你可以使用reduce函数完成所有这些,例如:

(def operations [ [:x #(reduce + (:values %))]    
                  [:y #(/ (:x %) 100)]      
                  [:z #(* (:y %) 10000000)]    
                ])

(defn build-map [a-map]
   (reduce (fn [s [k f]] (assoc s k (f s) ) ) a-map operations)
   )

(build-map {:values (range 8)})
Run Code Online (Sandbox Code Playgroud)