Разбить числовую последовательность в clojure - PullRequest
3 голосов
/ 28 октября 2010

У меня есть следующий ввод:

(def nums [123456789012 123456789012])

Я бы хотел следующий вывод:

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

* обратите внимание, что обе эти последовательности содержат числа, а не строки ...

Я подумал, что это было бы действительно просто сделать следующее:

  1. Конвертировать каждую запись в строку
  2. Разделить каждую строку на 4
  3. Преобразовать каждый раздел обратно в целое число

Вот моя неудачная попытка:

(defn split-nums [nums factor]
  (map
    #(map
       (fn [x] (Integer/valueOf (str x)))
       (partition factor (str %)))
  nums))

(println (split-nums nums, 4))

Когда я запускаю это, я получаю следующую ошибку:

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

Что говорит мне, что я имею дело с ленивой последовательностью, для которой мне нужно форсировать оценку, но когда я пытаюсь (str (doall x)), я получаю тот же результат.

Так что, эксперты, сомневаюсь, где я ошибаюсь? Это хороший подход? КСТАТИ. Я только начал изучать clojure, поэтому я, конечно, не эксперт.

Ответы [ 6 ]

7 голосов
/ 28 октября 2010

Зачем сначала конвертировать в строку?Вот версия с / и mod.Это также исправит проблему с ведущими нулями.

(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)))
4 голосов
/ 28 октября 2010

В этом случае я думаю, что это действительно хорошо для использования.У вас не так много карт.

(def nums [123456789012 123456789012])

(for [num nums] 
    (map #(Integer. (apply str %)) 
          (partition 4 (str num))))
;; => ((1234 5678 9012) (1234 5678 9012))
4 голосов
/ 28 октября 2010
(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"


Я, вероятно, напишу это, чтобы принять одно число, затем использовать map вместо взятияколл.

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


Если вы предпочитаете работать с целыми числами, а не со строками:

(mod 5151 10) ;; => 1 Получает наименее значимую цифру.

(/ 5151 10) ;; => 515 Удаляет наименее значимую цифру.

2 голосов
/ 28 октября 2010
user=> (map #(->> % (str) (partition 4) (map (fn [s] (read-string (apply str s))))) nums)
((1234 5678 9012) (1234 5678 9012))

Лучше извлечь функции.

2 голосов
/ 28 октября 2010

Небольшое изменение решения выше @nickik

(partition 3
  (map #(Integer. (apply str %))
       (partition 4 
         (apply concat (map str nums)))))
2 голосов
/ 28 октября 2010
(def nums [123456789012 123456789012])

(defn part-int [l n] 
  (map #(Integer. (apply str %)) 
    (partition l (str n))))

(map (partial part-int 4) nums)
;; => ((1234 5678 9012) (1234 5678 9012))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...