[英]Idiomatic way to convert some hash-map values to floats in Clojure
我有一个简单to-float
功能:
(defn to-float [v] (cond
(nil? v) nil
(string? v) (Float/parseFloat v)
:else (float v)))
并记录:
(defrecord Product [Id UseRecommendation ReferenceProductId OnePrice TotalPrice
ManualTotalPrice MarketTotalPrice PreviousTotalPrice PurchaseTotalPrice
Tax Deposit RuleId RoleId PrimaryProduct Size])
对于某些键(?),我希望在将它们传递给map->Product
(构造函数?)之前确保它们是浮动的。 抱歉,我对这里的术语不熟悉。
无论如何,我的第一个解决方案非常冗长:
(defn init->Product [args]
(let [converted-args (assoc args
:TotalPrice (to-float (:TotalPrice args))
:ManualTotalPrice (to-float (:ManualTotalPrice args))
:MarketTotalPrice (to-float (:MarketTotalPrice args))
:PreviousTotalPrice (to-float (:PreviousTotalPrice args))
:PurchaseTotalPrice (to-float (:PurchaseTotalPrice args))
:Tax (to-float (:Tax args))
:Deposit (to-float (:Deposit args)))]
(map->Product converted-args)))
第二个更好,但是在apply
, merge
, hash-map
等方面有很多“噪音”:
(defn init->Product [args]
(let [apply-float (fn [keys] (merge args (apply merge (map #(hash-map % (to-float (% args))) keys))))]
(map->Product (apply-float '(:TotalPrice :ManualTotalPrice :MarketTotalPrice :PreviousTotalPrice :PurchaseTotalPrice :Tax :Deposit)))))
第三种解决方案使用递归,这对于Clojure的新手来说都不容易理解:
(defn init->Product [args-orig]
(let [apply-float (fn [args keys] (if (empty? keys) args (let [key (first keys)] (recur (assoc args key (to-float (key args))) (rest keys)))))]
(map->Product (apply-float args-orig '(:TotalPrice :ManualTotalPrice :MarketTotalPrice :PreviousTotalPrice :PurchaseTotalPrice :Tax :Deposit)))))
您能想到更简单的方法吗? 我感觉这里缺少一个实用程序功能,或者我看不到如何使用reduce
或其他功能。
编辑:这更像我将如何在Python中做到这一点
(defn init->Product [args-orig]
(let [apply-float (fn [args keys] (merge args (into {} (map (fn [key] [key (to-float (key args))]) keys))))]
(map->Product (apply-float args-orig '(:TotalPrice :ManualTotalPrice :MarketTotalPrice :PreviousTotalPrice :PurchaseTotalPrice :Tax :Deposit)))))
可以使用(update m :xf)
代替(assoc m :x (f (:xm)))
(update m :xf)
。 因此,我将重写您的init->Product
函数,如下所示:
(defn init->Product [args]
(let [converted-args (reduce #(update %1 %2 to-float)
args
[:TotalPrice
:ManualTotalPrice
:MarketTotalPrice
:PreviousTotalPrice
:PurchaseTotalPrice
:Tax
:Deposit])]
(map->Product converted-args)))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.