How to split a number in Clojure?

I am looking for a good method to split a number into n digits in Clojure. I have these two detailed 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 way for this type of operation?

+7
source share
6 answers

A short version of your first method

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

..., and second -

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

Idiomatic alternative

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

For instance,

 (map digits [0 942 -3]) ;(nil (9 4 2) nil) 
  • The calculation, in essence, is impatient, since the last digit is at first. Therefore, we could use mapv and rseq (instead of map and reverse ) to make it faster.
  • The function is ready for operation of the inverter.
  • It only works correctly on positive numbers.
+8
source

You could just do

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

EDIT: Adding a function definition

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

Using:

 (digits 1234) 

Note. This is concise, but uses the Java String and Character classes. An effective implementation can be written using integer arithmetic modulo, but will not be concise. One such solution, similar to Charles's answer, would be:

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

A source

+8
source

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

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

Recursive implementation (may be more efficient and less concise, but that doesn't matter for reasonable numbers).

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

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))) ) ) ) 
0
source

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

0
source

Source: https://habr.com/ru/post/986186/


All Articles