我知道有很多相关的问题,我已经阅读了它们,但仍然没有对如何读取 - 处理 - 写入有一些基本的了解。以下面的函数为例,它使用clojure-csv
库来解析一行
(defn take-csv
"Takes file name and reads data."
[fname]
(with-open [file (reader fname)]
(doseq [line (line-seq file)]
(let [record (parse-csv line)]))))
我想获得的是(def data (take-csv "file.csv"))
之后读入某个集合的数据,然后再处理它。所以基本上我的问题是如何返回record
或更确切地说是记录列表。
答案 0 :(得分:8)
(defn take-csv
"Takes file name and reads data."
[fname]
(with-open [file (reader fname)]
(doall (map (comp first csv/parse-csv) (line-seq file)))))
更好地解析整个文件以减少代码:
(defn take-csv
"Takes file name and reads data."
[fname]
(with-open [file (reader fname)]
(csv/parse-csv (slurp file))))
您也可以使用clojure.data.csv而不是clojure-csv.core。只应该在前一个函数中将parse-csv重命名为take-csv。
(defn put-csv [fname table]
(with-open [file (writer fname)]
(csv/write-csv file table)))
答案 1 :(得分:2)
使用.csv文件可以做的所有事情,我建议使用clojure-csv或clojure.data.csv。我主要使用clojure-csv来读取.csv文件。
以下是我在大多数Clojure程序中使用的实用程序库中的一些代码片段。
from util.core
(ns util.core
^{:author "Charles M. Norton",
:doc "util is a Clojure utilities directory"}
(:require [clojure.string :as cstr])
(:import java.util.Date)
(:import java.io.File)
(:use clojure-csv.core))
(defn open-file
"Attempts to open a file and complains if the file is not present."
[file-name]
(let [file-data (try
(slurp file-name)
(catch Exception e (println (.getMessage e))))]
file-data))
(defn ret-csv-data
"Returns a lazy sequence generated by parse-csv.
Uses open-file which will return a nil, if
there is an exception in opening fnam.
parse-csv called on non-nil file, and that
data is returned."
[fnam]
(let [csv-file (open-file fnam)
inter-csv-data (if-not (nil? csv-file)
(parse-csv csv-file)
nil)
csv-data
(vec (filter #(and pos? (count %)
(not (nil? (rest %)))) inter-csv-data))]
(if-not (empty? csv-data)
(pop csv-data)
nil)))
(defn fetch-csv-data
"This function accepts a csv file name, and returns parsed csv data,
or returns nil if file is not present."
[csv-file]
(let [csv-data (ret-csv-data csv-file)]
csv-data))
一旦你读了.csv文件,那么你对它的内容所做的就是另一回事了。通常,我从一个金融系统中获取.csv“报告”,如财产评估,并将要上传的数据格式化为另一个金融系统的数据库,如计费。
我经常会zipmap
每个.csv行,所以我可以按列名提取数据(读取列名),甚至可以创建一系列zipmap
'ped .csv行。
答案 2 :(得分:0)
只需添加一个好的答案,这是一个完整的示例
首先,将clojure-csv添加到您的依赖项中
(ns scripts.csvreader
(:require [clojure-csv.core :as csv]
[clojure.java.io :as io]))
(defn take-csv
"Takes file name and reads data."
[fname]
(with-open [file (io/reader fname)]
(-> file
(slurp)
(csv/parse-csv))))
用法
(take-csv "/path/youfile.csv")