You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化Clojure代码:从多空格分隔文本列生成列表

优化Clojure列提取代码

输入数据

1    2
3    4
5    6
7    8
9    0

期望输出

((1 3 5 7 9) (2 4 6 8 0))

现有实现

(defn make-lists []
  (let [lines (clojure.string/split-lines (slurp "input"))]
    (let [l1 (map #(parse-long (first (clojure.string/split % #" "))) lines)
          l2 (map #(parse-long (nth (clojure.string/split % #" ") 3)) lines)]
      (list l1 l2))))

存在的问题

  • 对输入行进行了两次遍历,效率有优化空间
  • 使用#" "拆分多空格会产生大量空字符串,不得不硬编码nth 3来获取第二列,代码鲁棒性差,一旦空格数量变化就会出错

优化方案

方案一:利用转置特性一次处理

(defn make-lists []
  (->> (slurp "input")
       clojure.string/split-lines
       (map #(->> (clojure.string/split % #"\s+")
                  (map parse-long)))
       (apply map list)))

逻辑说明:

  1. 读取文件内容并按行拆分
  2. 对每一行用#"\s+"(匹配一个或多个空白字符)拆分,避免空字符串问题,再将拆分后的字符串转为长整型
  3. 通过apply map list将所有行的序列转置,直接得到以列为单位的两个列表,完全符合期望输出

方案二:用Reduce一次遍历收集

如果更倾向于显式的遍历收集,可以用reduce实现:

(defn make-lists []
  (let [result (reduce (fn [[col1 col2] line]
                         (let [[a b] (->> (clojure.string/split line #"\s+")
                                          (map parse-long))]
                           [(conj col1 a) (conj col2 b)]))
                       [() ()]
                       (clojure.string/split-lines (slurp "input")))]
    (list (first result) (second result))))

逻辑说明:

  1. 初始化两个空列表作为累加器,分别对应两列
  2. 遍历每一行,拆分并转换为数字后,将两个数分别追加到对应列的列表中
  3. 最后将累加器中的两个列表转为目标格式的list

这两个方案都解决了原代码的两个问题:仅遍历一次输入行,同时适配任意数量的分隔空格,鲁棒性更强。

内容的提问来源于stack exchange,提问作者user1785730

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 16:11:09