Clojure中的进步联想

Clojure中的进步联想,clojure,Clojure,我今天遇到了一件我需要的事情,我想在地图中逐步关联条目,每个条目都基于前一个(s)的结果。以下是我所做的: (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

我今天遇到了一件我需要的事情,我想在地图中逐步关联条目,每个条目都基于前一个(s)的结果。以下是我所做的:

(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)})

我欢迎你对a)这是件好事吗?b) 有没有一种我没有见过的现有方法?(我对API不太熟悉)

所以你得到了一个经过一些转换的映射,最后得到了一个最终的映射。在我看来,您的实现很好,除了
-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)})

我认为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})))

呵呵-my-Y函数实际上是一个let!这绝对是简单的,但不知何故让我毛骨悚然(不知道为什么),这就是为什么我避免做明显的事情。我觉得有一种更好的方式来表现这些渐进式的操作情况,但我才刚刚开始学习Clojure,所以我还不知道怎么做。