在Clojure中,从数字中获取数字列表是非常容易的:
user=> (digits 234432)
(2 3 4 4 3 2)
user=> (map type (digits 22))
(java.lang.Long java.lang.Long)
我的问题是如何反其道而行--如何从数字列表中创建一个数字?
编辑好点,如下所示:
(defn digits [n]
(->> n str (map (comp read-string str))))
它来自here
发布于 2016-07-21 08:56:14
我能想到两种方法:
使用reduce
boot.user=> (reduce (fn [a b] (+ b (* a 10))) 0 '(1 2 3 4 5))
12345
使用clojure.string/join
和Long/parseLong
boot.user=> (Long/parseLong (clojure.string/join '(1 2 3 4 5)))
12345
请注意,如果任何数字大于9,则这两种方法的行为并不相同。
如果您需要对bigints的支持,可以这样做:
boot.user=> (def digits (repeat 100 1))
#'boot.user/digits
boot.user=> digits
(1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
boot.user=> (reduce (fn [a b] (+ b (* a 10))) 0N digits)
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111N
boot.user=> (bigint (clojure.string/join digits))
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111N
发布于 2016-07-21 09:24:41
此外,还可以从核心库中选择使用read-string
或(最好是为了安全) clojure.edn/read-string
。这样做的好处是不必考虑整数溢出和转换为bigint,读者可以这样做:
user> (clojure.edn/read-string (apply str [1 2 3 4 5]))
12345
user> (clojure.edn/read-string (apply str (repeat 20 1)))
11111111111111111111N
作为一项附加功能,它支持每个clojure的数字文字:
浮动:
user> (clojure.edn/read-string (apply str [1 3 \. 2 4]))
13.24
二进制:
user> (clojure.edn/read-string (apply str "2r" [1 1 0 1]))
13
十六进制:
user> (clojure.edn/read-string (apply str "0x" [\f 2 \e 3]))
62179
任意(例如,基数5):
user> (clojure.edn/read-string (apply str "5r" [1 3 2 4]))
214
诸若此类。
https://stackoverflow.com/questions/38499290
复制相似问题