Clojure:在地图中绕过bigInt

Clojure: round bigInt in map

我需要地图方面的帮助。 从数据库中使用jdbc/query获取数据后,结果如下所示:

1
2
3
({:product_id 1, :name product1, :rating 3.000M}
 {:product_id 2, :name product2, :rating 1.333M}
 {:product_id 3, :name product3}, :rating nil)

我想用Selmer来显示所有内容,但只需要逗号后的1个数字。 像这样:

1
2
3
({:product_id 1, :name product1, :rating 3.0}
 {:product_id 2, :name product2, :rating 1.3}
 {:product_id 3, :name product3}, :rating nil)

我发现了如何遍历地图,但是我不知道如何更改特定值。 查询数据保存在data

1
2
3
4
(doseq [keyval data]
  (doseq [keyval2 keyval]
    (doseq [keyval3 keyval2]
      (prn keyval3))))

您能帮我创建一个新的data变量吗? 谢谢!


clojure数据是不可变的,因此您无法以通用方式对其进行更新。 相反,您可以使用clojure的数据操作功能来复制数据并添加所需的更改。 不错的介绍可以在这里找到:http://www.braveclojure.com/functional-programming/

所以你要做的就是这样

1
2
3
4
5
6
7
8
9
10
11
12
user> (defn round-to [^Double num places] (when num (Math/round num)))
#'user/round-to ;; not-a-real-round-to (simplified for brevity)

user> (def data '({:product_id 1, :name product1, :rating 3.000M}
                  {:product_id 2, :name product2, :rating 1.333M}
                  {:product_id 3, :name product3, :rating nil}))
#'user/data

user> (map #(update % :rating round-to 2) data)
;;=> ({:product_id 1, :name product1, :rating 3}
;;    {:product_id 2, :name product2, :rating 1}
;;    {:product_id 3, :name product3, :rating nil})

1
2
3
4
5
6
7
8
9
10
(defn round2
 "Round a double to the given precision (number of significant digits)"
  [precision d]
  (let [factor (Math/pow 10 precision)]
    (/ (Math/round (* d factor)) factor)))

(map #(assoc % :rating (when-some [r (:rating %)] (round2 1 r)))
    '({:product_id 1, :name 'product1, :rating 3.000M}
      {:product_id 2, :name 'product2, :rating 1.333M}
      {:product_id 3, :name 'product3, :rating nil}))