我想在 Clojure 中将“数字”字符串格式化为“字符串数字”。这是格式掩码:
"#,###,###,##0.00"
给定字符串“9999.99”,我希望收到“9,999.99”。
我将如何在 Clojure 中做到这一点而不求助于编写转换器函数,即使用format或类似的东西?
我想在 Clojure 中将“数字”字符串格式化为“字符串数字”。这是格式掩码:
"#,###,###,##0.00"
给定字符串“9999.99”,我希望收到“9,999.99”。
我将如何在 Clojure 中做到这一点而不求助于编写转换器函数,即使用format或类似的东西?
看来,在您的问题域中,二进制浮点数(例如 IEEE-754)的缺点和限制给您带来了一些困难。也许您应该考虑利用 Clojure 中已经内置的 BigDecimal 支持。在 Clojure 中,BigDecimal 常量和浮点常量之间的区别是单个字符;例如 1.2 是 Double,而 1.2M 是 BigDecimal。该bigdec函数可用于即时将事物转换为 BigDecimal。例如,
(format "%,.2f" (bigdec "9999999999999999.12"))
生产
"9,999,999,999,999,999.12"
正如预期的那样。算术函数,如*、+、-和/也可以按预期工作。
但是,这并不能解决您的基本问题。如果您的格式字符串不遵循 Java/Clojure 格式字符串约定,您将不得不编写一个转换器函数。
祝你好运。
您可以,在格式说明符中使用:
(format "%,.2f" (float (clojure.edn/read-string "9999")))
=> "9,999.00"
(format "%,.2f" (Double/parseDouble "9999.126"))
=> "9,999.13"
更新以包括bigdec示例:
(format "%,.2f" (bigdec "9999999999999999.12"))
=> "9,999,999,999,999,999.12"
您可以使用NumberFormat. 我也喜欢另一个答案(有关详细信息,请参阅Java 10Formatter文档):
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test)
(:import [java.text NumberFormat]
[java.util Locale]))
(dotest
(let [value (Double/valueOf "1234567.89")
nf (NumberFormat/getNumberInstance (Locale/US))
s1a (.format nf (.doubleValue value))
s1b (format "%,05.2f" value)]
(spyx s1a)
(spyx s1b))
s1a => "1,234,567.89"
s1b => "1,234,567.89"
(let [value (Double/valueOf "1.2")
nf (NumberFormat/getNumberInstance (Locale/US))
s1a (.format nf (.doubleValue value))
s1b (format "%,05.2f" value)]
(spyx s1a)
(spyx s1b)))
s1a => "1.2"
s1b => "01.20"
这是 BigDecimal 的操作方法,首先使用 Java 互操作,然后使用内置的 Clojure 函数bigdec:
(format "%,05.2f" (BigDecimal. "9999999999999999.12")) => "9,999,999,999,999,999.12"
(format "%,05.2f" (bigdec "9999999999999999.12")) => "9,999,999,999,999,999.12"