2016-04-12 2 views
9

Я хочу прочитать первые n строк из файла, используя clojure. Вот мой код:Как читать n строк из файла в clojure

(defn read-nth-line [file] 
    (with-open [rdr (reader file)] 
    (loop [line-number 0] 
     (when (< line-number 20) 
      (nth (line-seq rdr) line-number) 
      (recur (inc line-number)))))) 

, но когда я бегу

user=> (read-nth-line "test.txt") 

IndexOutOfBoundsException clojure.lang.RT.nthFrom (RT.java:871) 

Я понятия не имею, почему я получил такую ​​ошибку.

+0

«test.txt» содержит более 20 строк? – ClasG

+0

Можете ли вы добавить требование на свой вопрос? Мне нравится копировать код вставки в REPL: (require '[clojure.java.io: refer [читатель]]) –

ответ

18

Ваш код выдает ошибку за пределы, потому что вы вызываете line-seq несколько раз на одного и того же читателя. Если вы хотите, чтобы получить количество строк от читателя, вы должны вызвать line-seq только один раз, а затем взять нужное количество строк из этой последовательности:

(require '[clojure.java.io :as io]) 

(defn lines [n filename] 
    (with-open [rdr (io/reader filename)] 
    (doall (take n (line-seq rdr))))) 

Пример:

(run! println (lines 20 "test.txt")) 

Если test.txt содержит менее 20 строк, это просто напечатает все строки в файле.

+0

Можете ли вы добавить запрос на свой ответ? Мне нравится копировать код вставить в REPL (require '[clojure.java.io: Refer [reader]]) –

+1

@MichielBorkent Конечно; Я просто пытался отразить стиль OP. Я добавил 'require' с псевдонимом, потому что я предпочитаю использовать': as' over': refer', когда это возможно. –

Смежные вопросы