2012-11-30 41 views
5

Tôi biết có rất nhiều câu hỏi liên quan, tôi đã đọc chúng nhưng vẫn chưa đạt được một số hiểu biết cơ bản về cách đọc-ghi-viết. Hãy hàm sau ví dụ trong đó sử dụng clojure-csv thư viện để phân tích một dòngĐọc csv vào danh sách trong clojure

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

Những gì tôi muốn được là dữ liệu đọc vào một số bộ sưu tập như một kết quả của (def data (take-csv "file.csv")) và sau đó để xử lý nó. Vì vậy, về cơ bản câu hỏi của tôi là làm thế nào để tôi trả lại record hoặc đúng hơn là một danh sách các bản ghi.

Trả lời

7

"liềuq" thường được sử dụng cho các hoạt động có tác dụng phụ. Trong trường hợp của bạn để tạo ra bộ sưu tập các bản ghi, bạn có thể sử dụng "bản đồ":

(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 phân tích toàn bộ hồ sơ tại những để giảm mã:

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

Bạn cũng có thể sử dụng thay vì clojure.data.csv của clojure-csv.core. Chỉ nên đổi tên parse-csv thành take-csv trong hàm trước.

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

Tốt. Bây giờ tất cả còn lại là 'put-csv', bạn sẽ giúp gì? –

+0

Tôi đã thêm nội dung này. – mobyte

+0

Chú ý đến doall: doall có thể được sử dụng để buộc bất kỳ hiệu ứng nào. Đi qua các nexts kế tiếp của seq, giữ nguyên phần đầu và trả về, do đó làm cho toàn bộ số seq nằm trong bộ nhớ cùng một lúc. – micrub

2

Với tất cả những điều bạn có thể làm với tệp .csv, tôi khuyên bạn nên sử dụng clojure-csv hoặc clojure.data.csv. Tôi chủ yếu sử dụng clojure-csv để đọc trong tệp .csv.

Dưới đây là một số đoạn mã từ thư viện tiện ích tôi sử dụng với hầu hết các chương trình Clojure của mình.

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

Khi bạn đã đọc tệp .csv, thì nội dung bạn làm với nội dung của nó là một vấn đề khác. Thông thường, tôi đang dùng .csv "báo cáo" từ một hệ thống tài chính, như đánh giá tài sản và định dạng dữ liệu được tải lên cơ sở dữ liệu của hệ thống tài chính khác, như thanh toán.

Tôi thường hoặc là zipmap mỗi hàng .csv để tôi có thể trích xuất dữ liệu theo tên cột (đã đọc trong tên cột) hoặc thậm chí tạo một chuỗi các hàng .csv theo dõi zipmap.

+0

Cảm ơn bạn. Tuy nhiên, thật thú vị khi nghe nhận xét của bạn để đọc toàn bộ tệp vào bộ nhớ, điều này có thể là một vấn đề đối với [các tệp rất lớn] (http://clojurewise.blogspot.com/2011/02/reading-csv-files.html). –

+0

Theo như tôi có thể nói đó là một chuỗi bản đồ lười biếng. clojure-csv trả về một chuỗi chậm và zipmap cũng vậy. Đó là cách tôi làm điều đó. – octopusgrabbus

Các vấn đề liên quan