使用doseq读取文件直到Clojure中的某一行

ads*_*sco 2 clojure

这在其他语言中通常是微不足道的,但我在Clojure中找不到这样的例子.

我可以使用以下方法打印整个文件:

(with-open [rdr (io/reader "file")]
          (doseq [line (line-seq rdr) :while (< count(line) 10)]
            (println line)))
Run Code Online (Sandbox Code Playgroud)

但是如何让它停在第5行呢?

谢谢.

nta*_*lbs 7

你可以试试这个:

(println
 (with-open [rdr (clojure.java.io/reader "file")]
   (let [ls (line-seq rdr)]
     (doall (take 5 ls)))))
Run Code Online (Sandbox Code Playgroud)

这将打印指定文件的前5行.

如果您需要跳过一些不满足条件的行,您可以添加filter.以下代码将打印长度小于10的前五行.

(println
 (with-open [rdr (clojure.java.io/reader "file")]
   (let [ls (line-seq rdr)]
     (->> ls
          (filter #(< (count %) 10))
          (take 5)
          (doall)))))
Run Code Online (Sandbox Code Playgroud)

由于filtertake返回延迟序列,它应该在with-open表单内实现.在with-open表单之外,序列无法实现并导致异常.

println 函数也使序列实现,你可以像这样修改代码:

(with-open [rdr (clojure.java.io/reader "data/base_exp.txt")]
  (let [ls (line-seq rdr)]
    (->> ls
         (filter #(> (count %) 10))
         (take 5)
         (println))))
Run Code Online (Sandbox Code Playgroud)


Leo*_*hin 6

只需take用来限制行数:

更换

   (doseq [line (line-seq rdr) ;; ...
Run Code Online (Sandbox Code Playgroud)

   (doseq [line (take 5 (line-seq rdr)) ;; ...
Run Code Online (Sandbox Code Playgroud)