Прогрессивная ассоциация в Clojure - PullRequest
3 голосов
/ 08 декабря 2011

Я наткнулся на то, что мне было нужно сегодня, где я хотел постепенно связывать записи на карте, каждая из которых основывалась на результатах предыдущих.Вот что я сделал:

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

Я бы приветствовал ваши мысли по поводу а) это хорошо?б) есть ли способ сделать это, чего я еще не видел?(Я плохо знаю API)

Ответы [ 2 ]

10 голосов
/ 08 декабря 2011

Я думаю, что ответ от Анкура - это хорошее улучшение вашего оригинального дизайна.

Я просто хотел упомянуть, что не всегда необходимо слишком усложнять вещи.В любом случае, если вы вычислите все дополнительные записи карты в одной и той же функции, этот простой подход станет гораздо более читабельным, на мой взгляд:

(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})))
7 голосов
/ 08 декабря 2011

Итак, у вас есть карта, которая проходит через некоторые преобразования, и в итоге вы получаете окончательную карту.Ваша реализация выглядит хорошо для меня, за исключением того, что -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)})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...