Search code examples
clojure

Read csv into a list in clojure


I know there are a lot of related questions, I have read them but still have not gained some fundamental understanding of how to read-process-write. Take the following function for example which uses clojure-csv library to parse a line

(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)]))))

What I would like to obtain is data read into some collection as a result of (def data (take-csv "file.csv")) and later to process it. So basically my question is how do I return record or rather a list of records.


Solution

  • "doseq" is often used for operations with side effect. In your case to create collection of records you can use "map":

    (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)))))
    

    Better parse the whole file at ones to reduce code:

    (defn take-csv
      "Takes file name and reads data."
      [fname]
      (with-open [file (reader fname)]
        (csv/parse-csv (slurp file))))
    

    You also can use clojure.data.csv instead of clojure-csv.core. Only should rename parse-csv to take-csv in previous function.

    (defn put-csv [fname table]
      (with-open [file (writer fname)]
        (csv/write-csv file table)))