繁体   English   中英

将某些哈希映射值转换为Clojure中的float的惯用方式

[英]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)))

第二个更好,但是在applymergehash-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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM