0

ファイルを 1 行ずつ読み込んで、各行の末尾に新しい文字列を連結しようとしています。テストのために、私はこれを行いました:

(defn read-file
[filename]
(with-open [rdr (clojure.java.io/reader filename)]
  (doall (line-seq rdr))))

(apply str ["asdfasdf" (doall (take 1 (read-file filename)))])

(take 1 (read-file filename))repl で評価すると、ファイルの最初の行が取得されます。ただし、上記で行ったことを評価しようとすると、"asdfasdfclojure.lang.LazySeq@4be5d1db".

take強制的に評価して遅延シーケンスを返さないようにする方法を誰かが説明できますか?

4

1 に答える 1

1

この関数は設計上遅延しているため、 、 、またはtakeを使用して必要な値を実現するか、 、first、、またはなどの関数を使用して seq 全体を操作する必要がある場合があります。nextnthapplyreducevecinto

あなたの場合、次のことをしようとしているようです:

(apply str ["asdfasdf" (apply str (take 1 (read-file filename)))])

または:

(str "asdfasdf" (first (read-file filename)))


を使用して lazyseq 全体を実現することもできますdoall。実現されたレイジー seq はまだ seq であることに注意してください。

(realized? (take 1 (read-file filename))) ;; => false
(type (take 1 (read-file filename))) ;; => clojure.lang.LazySeq

(realized? (doall (take 1 (read-file filename)))) ;; => true
(type (doall (take 1 (read-file filename)))) ;; => clojure.lang.LazySeq


より良いオプションは、 のようなものを使用して変換を遅延して適用mapし、結果の seq から必要な値を選択することです。(ストリーム処理のように。)

(first (map #(str "prefix" % "suffix")
             (read-file filename)))

注: mapは遅延しているため、未実現の LazySeq が返されます。

于 2013-10-10T15:23:04.337 に答える