在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
答案 0 :(得分:4)
我能想到的两种方式:
使用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
答案 1 :(得分:1)
此外,还可以选择使用核心库中的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
等等。