从文件读取时在Clojure中拆分行 [英] Split lines in clojure while reading from file
问题描述
我正在学校学习Clojure,并且即将参加考试。我只是在做一些事情,以确保我掌握了窍门。
I am learning clojure at school and I have an exam coming up. I was just working on a few things to make sure I get the hang of it.
我试图逐行从文件中读取,并且我想在有;的情况下拆分行。
I am trying to read from a file line by line and as I do, I want to split the line whenever there is a ";".
到目前为止,这是我的代码
Here is my code so far
(defn readFile []
(map (fn [line] (clojure.string/split line #";"))
(with-open [rdr (reader "C:/Users/Rohil/Documents/work.txt.txt")]
(doseq [line (line-seq rdr)]
(clojure.string/split line #";")
(println line)))))
执行此操作后,仍会得到输出:
When I do this, I still get the output:
"I;Am;A;String;"
我错过了什么吗?
推荐答案
我不确定您是否在学校需要这个,但是由于加里(Gary)已经给出了一个很好的答案,因此可以将此视为奖励。
I'm not sure if you need this at school, but since Gary already gave an excellent answer, consider this as a bonus.
您可以使用换能器对文本行进行优雅的转换。您需要的成分是使您可以将这些行视为可还原的集合,并在完成还原后将其关闭的读者:
You can do elegant transformations on lines of text with transducers. The ingredient you need is something that allows you to treat the lines as a reducible collection and which closes the reader when you're done reducing:
(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
的情况下,您可以执行以下操作:
Now you're able to do the following, given input work.txt
:
I;am;a;string
Next;line;please
计算每个'split'的长度
(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")))
或带有占用时间
:
(transduce
(comp
(mapcat #(str/split % #";"))
(map count)
(take-while #(> 5 %)))
+
(lines-reducible (io/reader "/tmp/work.txt")))
阅读 https://tech.grammarly.com/blog/building-etl-pipelines-with-clojure 了解更多详情。
这篇关于从文件读取时在Clojure中拆分行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!