我不确定你在学校是否需要这个,但由于加里已经给出了很好的答案,请将此视为奖励。
您可以使用转换器对文本行进行优雅的转换。您需要的成分是允许您将行视为可简化集合的东西,并且在完成简化后关闭读者:
(defn lines-reducible [^BufferedReader rdr]
(reify clojure.lang.IReduceInit
(reduce [this f init]
(try
(loop [state init]
(if (reduced? state)
@state
(if-let [line (.readLine rdr)]
(recur (f state line))
state)))
(finally
(.close rdr))))))
现在,根据给定的输入,您可以执行以下操作work.txt
:
I;am;a;string
Next;line;please
计算每个“分割”的长度
(require '[clojure.string :as str])
(require '[clojure.java.io :as io])
(into []
(comp
(mapcat #(str/split % #";"))
(map count))
(lines-reducible (io/reader "/tmp/work.txt")))
;;=> [1 2 1 6 4 4 6]
将所有“分割”的长度相加
(transduce
(comp
(mapcat #(str/split % #";"))
(map count))
+
(lines-reducible (io/reader "/tmp/work.txt")))
;;=> 24
将所有单词的长度相加,直到找到长度超过 5 的单词
(transduce
(comp
(mapcat #(str/split % #";"))
(map count))
(fn
([] 0)
([sum] sum)
([sum l]
(if (> l 5)
(reduced sum)
(+ sum l))))
(lines-reducible (io/reader "/tmp/work.txt")))
or with take-while
:
(transduce
(comp
(mapcat #(str/split % #";"))
(map count)
(take-while #(> 5 %)))
+
(lines-reducible (io/reader "/tmp/work.txt")))
Read https://tech.grammarly.com/blog/building-etl-pipelines-with-clojure https://tech.grammarly.com/blog/building-etl-pipelines-with-clojure更多细节。