How to split a number in Clojure?

感情迁移 提交于 2019-12-22 04:20:11

问题


I am looking for a nice method to split a number with n digits in Clojure I have these two verbose inefficient methods:

 (->> (str 942)
      seq
      (map str)
      (map read-string)) => (9 4 2)

and...

(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)

Is there a more concise method for doing this type sort of operation?


回答1:


A concise version of your first method is

(defn digits [n]
  (->> n str (map (comp read-string str))))

... and of your second is

(defn digits [n]
  (if (pos? n)
    (conj (digits (quot n 10)) (mod n 10) )
    []))

An idiomatic alternative

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

For example,

(map digits [0 942 -3])
;(nil (9 4 2) nil)
  • The computation is essentially eager, since the last digit in is the first out. So we might as well use mapv and rseq (instead of map and reverse) to do it faster.
  • The function is transducer-ready.
  • It works properly only on positive numbers.



回答2:


You could simply do

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

EDIT: Adding a function definition

(defn digits [number] (map #(Character/digit % 10) (str number)))

Usage:

(digits 1234)

Note: This is concise, but does use java String and Character classes. An efficient implementation can be written using integer modulo arithmetic, but won't be concise. One such solution similar to Charles' answer would be:

(defn numTodigits
  [num]
  (loop [n num res []]
    (if (zero? n)
      res
      (recur (quot n 10) (cons (mod n 10) res)))))

Source




回答3:


I'm not sure about concise, but this one avoids unnecessary inefficiency such as converting to strings and back to integers.

(defn digits [n]
  (loop [result (list), n n]
    (if (pos? n)
      (recur (conj result (rem n 10))
             (quot n 10))
      result)))



回答4:


A recursive implementation (could be more efficient and less concise, but it shouldn't matter for reasonable numbers).

(defn digits [n]
  (when (pos? n)
    (concat (digits (quot n 10))
            [(mod n 10)])))



回答5:


a looping method:

 (defn split-numbers [number]
   (loop [itr 0 res [] n number]
     (if (= n 0)
       res
       (recur (inc itr) (concat (vector (mod n 10)) res) (int (/ n 10)))
       )
     )
   )



回答6:


Easiest i could find:

(->> (str n)
   seq
   (map (comp read-string str)))


来源:https://stackoverflow.com/questions/29929325/how-to-split-a-number-in-clojure

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!