ファイルでは、どのようにして各行がシーケンス内の1つの要素であるかを順番にファイルを読み込みます。だから私は、私は次のことを行うことができます機能get-lines
の定義を見てみたいと思います:ファイルをリストに読み込み、各要素はファイルの1行を表します
(def lines (get-lines "test.txt"))
と行が非怠惰なシーケンスです。
ファイルでは、どのようにして各行がシーケンス内の1つの要素であるかを順番にファイルを読み込みます。だから私は、私は次のことを行うことができます機能get-lines
の定義を見てみたいと思います:ファイルをリストに読み込み、各要素はファイルの1行を表します
(def lines (get-lines "test.txt"))
と行が非怠惰なシーケンスです。
非怠惰あなたがそうのようなdoall
を使用することができますに怠惰なシーケンスを変換するには:
(use 'clojure.java.io)
(defn get-lines [fname]
(with-open [r (reader fname)]
(doall (line-seq r))))
line-seq
を使用できます。簡単な例:
(ns your.project
(:require [clojure.java.io :as io]))
(defn count-lines [filename]
(with-open [rdr (io/reader filename)]
(count (line-seq rdr))))
注line-seq
がlazyであること。あなたはの読者が閉じられた後にシーケンスを消費しないように注意する必要があります。以下は動作しません。
(def lines (with-open [rdr (io/reader "some-file")]
(line-seq rdr)))
(println (first lines))
count
は怠け者ではありませんので、最初の例は動作します。
あなたが線で(副作用で)何かをしたい場合は、おそらくdoseq
が最も有用見つけることができます:
;; copy every "short" line in file
(with-open [rdr (io/reader from)
wrt (io/writer to)]
(binding [*out* wrt]
(doseq [line (line-seq rdr) :when (< (count line) 10)]
(println line))))
代替実装:
(require ['clojure.string :as 'str])
(defn get-lines [file]
(str/split-lines (slurp file)))
この関数は、seqの代わりに結果のベクトルを返します。
1.3を使用していない場合は、代わりにclojure.contrib.stringが必要です。
:doallは、私が探していたキーでした。私は、ファイルをクローズした後にそのまま/使用可能だったリストが必要でした。 – ftravers