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

时间:2021-02-04 22:51:34

This would normally be trivial in other language, but I've found no such example in Clojure.

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

I can println an entire file using:

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

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

But how do I get it to stop at line 5?

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

Thanks.

2 个解决方案

#1


You can try this:

你可以试试这个:

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

This will print first 5 lines of the specified file.

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

If you need skip some lines that does not satisfy the condition, you can add filter. The following code will print first five lines that the length is less than 10.

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

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

Since filter and take returns lazy sequence, it should be realized within the with-open form. Outside the with-open form, the sequence couldn't be realized and cause exception.

由于filter和take返回延迟序列,因此应该在with-open形式内实现。在开放形式之外,序列无法实现并导致异常。

println function also make the sequence realized, you can modify the code like this:

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

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

#2


Simply use take to limit the amount of lines:

只需使用take来限制行数:

Replace

   (doseq [line (line-seq rdr) ;; ...

with

   (doseq [line (take 5 (line-seq rdr)) ;; ...

#1


You can try this:

你可以试试这个:

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

This will print first 5 lines of the specified file.

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

If you need skip some lines that does not satisfy the condition, you can add filter. The following code will print first five lines that the length is less than 10.

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

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

Since filter and take returns lazy sequence, it should be realized within the with-open form. Outside the with-open form, the sequence couldn't be realized and cause exception.

由于filter和take返回延迟序列,因此应该在with-open形式内实现。在开放形式之外,序列无法实现并导致异常。

println function also make the sequence realized, you can modify the code like this:

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

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

#2


Simply use take to limit the amount of lines:

只需使用take来限制行数:

Replace

   (doseq [line (line-seq rdr) ;; ...

with

   (doseq [line (take 5 (line-seq rdr)) ;; ...