I have the following input:

(def nums [123456789012 123456789012])

I'd like the following output:

[[1234 5678 9012] [1234 5678 9012]]

Note both of these sequence contain numbers not strings...

I figured this would be really simple by doing the following:

Convert each entry into a String

Partition each string by 4

Convert each partition back into an integer

**Attempt 1:**

(defn split-nums [nums factor]

(map

#(map

(fn [x] (Integer/valueOf (str x)))

(partition factor (str %)))

nums))

(println (split-nums nums, 4))

When I run this I get the following error:

Caused by: java.lang.NumberFormatException: For input string: "clojure.lang.LazySeq@4834333c"

Which tells me I am dealing with a lazy sequence that I need to force evaluation on but when I try to (str (doall x)) I get the same result.

**Attempt 2:**

A version with / and mod. This also fixes leading zeros problem.

(defn int-partition [num size]

(let [f (int (Math/pow 10 size))]

(loop [n num l ()]

(if (zero? n)

(vec l)

(recur (int (/ n f)) (conj l (mod n f)))))))

(defn split-nums [nums factor] (vec (map #(int-partition % factor) nums)))

**Attempt 3:**

(defn split-nums [nums factor]

(map #(map (fn [x] (Integer/valueOf (apply str x))) ; apply str

(partition factor (str %)))

nums))

(str (lazy-seq [1])) ; "clojure.lang.LazySeq@20"

(apply str (lazy-seq [1])) ; "1"

I'd probably write it to accept one number, then use map, instead of taking a coll.

(defn split-number [n factor]

(->> (str n)

(partition-all factor) ;; or partition

(map (partial apply str))

(map #(Integer/valueOf %))))

(map #(split-number % 4) [12345678 12345678]) ;; => ((1234 5678) (1234 5678))

Bingo!

## No comments:

## Post a Comment