在clojure中对数字序列进行分区

时间:2010-10-27 20:45:54

标签: clojure

我有以下输入:

(def nums [123456789012 123456789012])

我想要以下输出:

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

*注意这两个序列都包含数字而不是字符串......

我认为通过以下操作会非常简单:

  1. 将每个条目转换为字符串
  2. 将每个字符串分区为4
  3. 将每个分区转换回整数
  4. 这是我失败的尝试:

    (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专家哪里出错了?这是一个好方法吗? BTW。我刚刚开始学习clojure,所以我当然不是专家。

6 个答案:

答案 0 :(得分:7)

为什么先转换为String?这是一个/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)))

答案 1 :(得分:4)

(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 :(得分:4)

在这种情况下,我认为使用非常好。你没有那么多地图。

(def nums [123456789012 123456789012])

(for [num nums] 
    (map #(Integer. (apply str %)) 
          (partition 4 (str num))))
;; => ((1234 5678 9012) (1234 5678 9012))

答案 3 :(得分:2)

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

答案 4 :(得分:2)

@nickik

的解决方案略有变化
(partition 3
  (map #(Integer. (apply str %))
       (partition 4 
         (apply concat (map str nums)))))

答案 5 :(得分:2)

user=> (map #(->> % (str) (partition 4) (map (fn [s] (read-string (apply str s))))) nums)
((1234 5678 9012) (1234 5678 9012))

最好提取功能。