从文件读取时在Clojure中拆分行 [英] Split lines in clojure while reading from file

查看:60
本文介绍了从文件读取时在Clojure中拆分行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学校学习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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆