0

我正在尝试逐行读取文件并将新字符串连接到每行的末尾。为了测试我已经这样做了:

(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)))])

如果我只是在 repl 中评估(take 1 (read-file filename)),我会得到文件的第一行。但是,当我尝试评估我在上面所做的事情时,我得到"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)))


你也可以使用doall. 请记住,实现的惰性序列仍然是序列。

(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,然后从结果序列中选择你想要的值。(如流处理。)

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

注意: map是惰性的,所以它会返回一个未实现的 LazySeq。

于 2013-10-10T15:23:04.337 回答