如何拆分Clojure中的数字?

ade*_*sin 7 clojure

我正在寻找一个很好的方法来分割Clojure中的n位数字我有这两个冗长的低效方法:

 (->> (str 942)
      seq
      (map str)
      (map read-string)) => (9 4 2)
Run Code Online (Sandbox Code Playgroud)

和...

(defn digits [n] ;YUK!!
   (cons 
      (str (mod n 10)) (lazy-seq (positive-numbers (quot n 10)))))

(map read-string (reverse (take 5 (digits 10012)))) => (1 0 0 1 2)
Run Code Online (Sandbox Code Playgroud)

有没有更简洁的方法来进行这种类型的操作?

vsn*_*nyc 8

你可以干脆做

(map #(Character/digit % 10) (str 942))

编辑:添加功能定义

(defn digits [number] (map #(Character/digit % 10) (str number)))
Run Code Online (Sandbox Code Playgroud)

用法:

(digits 1234)
Run Code Online (Sandbox Code Playgroud)

注意:这很简洁,但确实使用java String和Character类.可以使用整数模运算来编写有效的实现,但不会简洁.类似于查尔斯答案的一个这样的解决方案是:

(defn numTodigits
  [num]
  (loop [n num res []]
    (if (zero? n)
      res
      (recur (quot n 10) (cons (mod n 10) res)))))
Run Code Online (Sandbox Code Playgroud)

资源


Thu*_*ail 8

第一种方法的简洁版本是

(defn digits [n]
  (->> n str (map (comp read-string str))))
Run Code Online (Sandbox Code Playgroud)

......而你的第二个是

(defn digits [n]
  (if (pos? n)
    (conj (digits (quot n 10)) (mod n 10) )
    []))
Run Code Online (Sandbox Code Playgroud)

一个惯用的替代品

(defn digits [n]
  (->> n
       (iterate #(quot % 10))
       (take-while pos?)
       (mapv #(mod % 10))
       rseq))
Run Code Online (Sandbox Code Playgroud)

例如,

(map digits [0 942 -3])
;(nil (9 4 2) nil)
Run Code Online (Sandbox Code Playgroud)
  • 计算基本上是渴望,因为去年的数字中是 第一个 出来.所以我们不妨使用mapv和rseq(而不是map和reverse)更快地完成它.
  • 该功能准备好传感器.
  • 它仅适用于正数.


Cha*_*ffy 5

我不确定简洁,但这个避免了不必要的低效率,如转换为字符串和返回整数.

(defn digits [n]
  (loop [result (list), n n]
    (if (pos? n)
      (recur (conj result (rem n 10))
             (quot n 10))
      result)))
Run Code Online (Sandbox Code Playgroud)