我正试图弄清楚我的代码出了什么问题。基本上它背后的想法是我正在读取一个非常大的文件,并且在文件中每行的末尾是一个数字。我想计算末尾数字大于500的行数。
我所拥有的就是这个,而且在纸面上它应该有用,但是出了点问题,我一直都没错。
(defn countlines [] (with-open [rdr (clojure.java.io/reader "myfile.txt")]
(doseq [line (line-seq rdr)]
(count (re-find #"(?!500)[56789]\d{2,}|\d{4,}$" line)))))
答案 0 :(得分:4)
原因是您使用doseq
:
clojure.core / doseq [seq-exprs&身体] 宏 在1.0中添加 反复执行身体(可能是副作用) 绑定和过滤由“for”提供。不保留 序列的头部。 返回nil。
您应该将其重写为类似(doall (for [line (line-seq rdr)] ...
但要完成你的任务,你需要重写它(因为你的函数会在匹配中返回一系列字符数:
user> (count (re-find #"\d+" "123k456"))
3
这显然不是你想要的
您需要做的是:
(count (filter #(re-find #"(?!500)[56789]\d{2,}|\d{4,}$" %)
(line-seq rdr)))
答案 1 :(得分:1)
如果我正确理解了这个问题,你应该这样做:
(defn countlines [] (with-open [rdr (clojure.java.io/reader "myfile.txt")]
(-> (line-seq rdr)
(filter #(re-find #"(?!500)[56789]\d{2,}|\d{4,}$" %))
(count))))
答案 2 :(得分:0)
关于Martin Lechner的回答,我认为应该使用Thread last( - >>)而不是Thread first( - >)。所以它应该是
(defn countlines [] (with-open [rdr (clojure.java.io/reader "myfile.txt")] (->> (line-seq rdr)
(filter #(re-find #"(?!500)[56789]\d{2,}|\d{4,}$" %))
(count))))