6

関連する質問がたくさんあることは知っています。それらを読んだことはありますが、読み取り、処理、書き込みの方法についての基本的な理解はまだ得られていません。たとえば、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つまり、基本的に私の質問は、レコードのリストをどのように返すかということです。

4

3 に答える 3

10

「doseq」は、副作用のある操作によく使用されます。レコードのコレクションを作成する場合は、「マップ」を使用できます。

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

コードを減らすために、ファイル全体を1つずつ解析することをお勧めします。

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

clojure-csv.coreの代わりにclojure.data.csvを使用することもできます。前の関数では、parse-csvの名前をtake-csvに変更する必要があります。

(defn put-csv [fname table]
  (with-open [file (writer fname)]
    (csv/write-csv file table)))
于 2012-11-30T09:20:14.040 に答える
3

.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ファイルを読み込んだら、その内容をどのように処理するかは別の問題です。通常、私は資産査定などの1つの金融システムから.csv「レポート」を取得し、請求などの別の金融システムのデータベースにアップロードするデータをフォーマットしています。

多くの場合、zipmap各.csv行を使用して、列名でデータを抽出できるようにするか(列名を読み込んで)、一連のzipmap.csv行を作成します。

于 2012-11-30T13:44:15.750 に答える
2

この良い答えを追加するために、ここに完全な例があります

まず、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")

于 2019-11-27T12:00:58.343 に答える