使用Clojure data.csv从一条输入线流传输多条输出线

时间:2018-07-19 00:48:07

标签: clojure

我正在读取一个csv文件,处理输入,将输出附加到输入,并将结果写入输出csv。似乎很简单。我正在使用 Clojure data.csv 。但是,我在输出中遇到了细微差别,这与我之前使用Clojure遇到的任何内容都不适合,我无法弄清楚。输出将为每个输入包含0到N行,我无法弄清楚如何将其流式传输到调用fn。

这是正在处理文件的表单:

\documentclass{report}

\usepackage{hyperref}

\title{Title}
\author{Author}

\begin{document}

\begingroup
\renewcommand{\thepage}{T}
\maketitle % Page T
\endgroup

\tableofcontents % Page 1

\chapter{A chapter} % Page 2

\end{document}

这是处理每一行的形式(返回0到N行,每行需要写入到输出csv):

(defn process-file
  [from to]
  (let [ctr (atom 0)]
    (with-open [r (io/reader from)
                w (io/writer to)]
      (some->> (csv/read-csv r)
               (map #(process-line % ctr))
               (csv/write-csv w)))))

2 个答案:

答案 0 :(得分:2)

老实说,我不完全理解您的问题,但是从您的评论中,我似乎已经回答了。

如果您要为返回的每一行运行select EmailID, Name, Mobile from Table_db1 union -- on purpose to remove duplicates select EmailID, Name, Mobile from Table_db2; ,则可以仅映射行:

select EmailID, Name, Mobile
from Table_db1
union all
select EmailID, Name, Mobile
from Table_db2 t2
where not exists (select 1 from Table_db1 t1 where t1.EmailID = t2.EmailID);

请注意,由于您正在产生副作用,因此我使用csv/write-csv。根据上下文,如果仅使用(some->> (csv/read-csv r) (map #(process-line % ctr)) (mapv #(csv/write-csv w %)))) ,则延迟可能会阻止写入。

但是使用mapv可能更正确:

map

doseq清楚地表明,迭代的目的是产生副作用,而不是生成新的(不可变的)列表。

答案 1 :(得分:1)

我认为您遇到的问题是您的map函数process-line返回的是零对多行的集合,因此当您map遍历输入行时,当您只想将一个(行)集合发送到write-csv时,获得一个集合的集合。如果是这样,解决方法就是将这一行更改为使用mapcat

(mapcat #(process-line % ctr))

mapcat类似于map,但它将“ process-line”调用的结果集合“合并”到单个集合中。