数字再次回到数字

时间:2016-07-21 08:44:16

标签: clojure

在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

2 个答案:

答案 0 :(得分:4)

我能想到的两种方式:

使用reduce

boot.user=> (reduce (fn [a b] (+ b (* a 10))) 0 '(1 2 3 4 5))
12345

使用clojure.string/joinLong/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

等等。