概要
- 指定した入力ポートからデータを読み込んで、SKILL で処理しやすい形式のデータを返す。
- ダブルクオートの処理や空白文字の処理は Microsoft Excel の処理を基準にする。
- CR、LF、CR-LF のどの改行方式でも対応する。
- 効率優先の実装。
- 関数としては SKILL 組み込みの以外のものは使わない。
jp_wikiwiki_aiou_Csv_toRecordList
- 出力結果は〈〈値のリスト〉のリスト〉とする。
jp_wikiwiki_aiou_Csv_toMapList
- 出力結果は〈〈〈キーと値のタプル〉のリスト〉のリスト〉とする。
- ヘッダ行のフィールド数と本体のフィールド数が違う場合の処理は Windows PowerShell の Import-Csv コマンドを基準にする。
コード
(inScheme (define (jp_wikiwiki_aiou_Csv_toRecordList inputPort) (letseq ( (inputPort__isEOF nil) ; boolean (inputPort__bufferIsReady nil) ; boolean (inputPort__buffer nil) ; char (inputPort_readChar (lambda () (cond (inputPort__isEOF nil) ; nil as eof-object (inputPort__bufferIsReady (setq inputPort__bufferIsReady nil) inputPort__buffer ) (else (setq inputPort__buffer (getc inputPort)) (setq inputPort__isEOF (null inputPort__buffer)) inputPort__buffer ) ) )) (inputPort_peekChar (lambda () (cond (inputPort__isEOF nil) ; nil as eof-object (inputPort__bufferIsReady inputPort__buffer) (else (setq inputPort__buffer (getc inputPort)) (setq inputPort__bufferIsReady t) (setq inputPort__isEOF (null inputPort__buffer)) inputPort__buffer ) ) )) (CharList_toString (lambda (this) (if this (apply strcat this) "") )) ) (if (null (inputPort_peekChar)) nil ; null as eof-object? (letseq ( (chars (list nil)) (chars_last chars ) (fields (list nil)) (fields_last fields ) (records (list nil)) (records_last records) ) (let parseLine ((c (inputPort_readChar))) (cond ((null c) ; null as eof-object? (when (or (pairp (cdr chars)) (pairp (cdr fields))) (setcdr fields_last (list (CharList_toString (cdr chars)))) (setcdr records_last (list (cdr fields))) ) (cdr records) ) ; null ((eq c '\r) (let ((nextChar (inputPort_peekChar))) (cond ((null nextChar) nil) ((eq '\n nextChar) (inputPort_readChar)) ) (if (or (pairp (cdr chars)) (pairp (cdr fields))) (begin (setcdr fields_last (list (CharList_toString (cdr chars)))) (setcdr records_last (list (cdr fields))) (setq records_last (cdr records_last)) ) ) (setcdr fields nil) (setq fields_last fields) (setcdr chars nil) (setq chars_last chars ) (parseLine (inputPort_readChar)) ) ) ; '\r ((eq c '\n) (when (or (pairp (cdr chars)) (pairp (cdr fields))) (setcdr fields_last (list (CharList_toString (cdr chars)))) (setcdr records_last (list (cdr fields))) (setq records_last (cdr records_last)) ) (setcdr fields nil) (setq fields_last fields) (setcdr chars nil) (setq chars_last chars ) (parseLine (inputPort_readChar)) ) ; '\n ((eq c '\") (if (null (cdr chars)) (let parseQuoted ((c (inputPort_readChar))) (cond ((null c) ; null as eof-object? (when (or (pairp (cdr chars)) (pairp (cdr fields))) (setcdr fields_last (list (CharList_toString (cdr chars)))) (setcdr records_last (list (cdr fields))) ) (cdr records) ) ((eq c '\") (case (inputPort_peekChar) ((\") (inputPort_readChar) (setcdr chars_last (list '\")) (setq chars_last (cdr chars_last)) (parseQuoted (inputPort_readChar)) ) ((\,) (parseLine (inputPort_readChar))) (else (parseQuoted (inputPort_readChar))) ) ) (else (setcdr chars_last (list c)) (setq chars_last (cdr chars_last)) (parseQuoted (inputPort_readChar)) ) ) ) ; let parseQuoted ; else (begin (setcdr chars_last (list c)) (setq chars_last (cdr chars_last)) (parseLine (inputPort_readChar)) ) ) ) ; '\" ((eq c '\,) (setcdr fields_last (list (CharList_toString (cdr chars)))) (setq fields_last (cdr fields_last)) (setcdr chars nil) (setq chars_last chars) (parseLine (inputPort_readChar)) ) ; '\, (t (setcdr chars_last (list c)) (setq chars_last (cdr chars_last)) (parseLine (inputPort_readChar)) ) ) ; cond ) ; let parseLine ) ; letseq ) ; if null ) ; letseq ) ; define jp_wikiwiki_aiou_Csv_toRecordList
(define (jp_wikiwiki_aiou_Csv_toMapList inputPort) (let ((rl (jp_wikiwiki_aiou_Csv_toRecordList inputPort))) (and rl (let ((head (car rl)) (body (cdr rl))) (mapcar (lambda (values) (letseq ((buffer (list nil)) (buffer_last buffer)) (let keyValue ((ks head) (vs values)) (cond ((null ks) (cdr buffer)) ((null vs) (setcdr buffer_last (list (list (car ks) ""))) (setq buffer_last (cdr buffer_last)) (keyValue (cdr ks) nil) ) (t (setcdr buffer_last (list (list (car ks) (car vs)))) (setq buffer_last (cdr buffer_last)) (keyValue (cdr ks) (cdr vs)) ) ) ; cond ) ; let keyValue ) ; letseq ) ; lambda body ) ; mapcar body ) ; let head, body ) ; and rl ) ; let rl ) ; define jp_wikiwiki_aiou_Csv_toMapList ) ; inScheme
使用例
ファイル「Presidents.csv」の中身は以下のとおり。
$ cat Presidents.csv name,company,address,city "LINCOLN, Abraham","Benton, John B Jr",6649 N Blue Gum St,New Orleans "CARTER, Jimmy","Chanay, Jeffrey A Esq",4 B Blue Ridge Blvd,Brighton "ROOSEVELT, Franklin","Chemel, James L Cpa",8 W Cerritos Ave #54,Bridgeport "BUSH, George",Feltz Printing Service,639 Main St,Anchorage "CLINTON, Bill",Printing Dimensions,34 Center St,Hamilton "OBARAM, Barack","Chapman, Ross E Esq",3 Mcauley Dr,Ashland $
jp_wikiwiki_aiou_Csv_toRecordList
(letseq ( (inputPort (infile "Presidents.csv")) (recordList (jp_wikiwiki_aiou_Csv_toRecordList inputPort)) ) (close inputPort) recordList ) → ( ("name" "company" "address" "city") ("LINCOLN, Abraham" "Benton, John B Jr" "6649 N Blue Gum St" "New Orleans") ("CARTER, Jimmy" "Chanay, Jeffrey A Esq" "4 B Blue Ridge Blvd" "Brighton") ("ROOSEVELT, Franklin" "Chemel, James L Cpa" "8 W Cerritos Ave #54" "Bridgeport") ("BUSH, George" "Feltz Printing Service" "639 Main St" "Anchorage") ("CLINTON, Bill" "Printing Dimensions" "34 Center St" "Hamilton") ("OBARAM, Barack" "Chapman, Ross E Esq" "3 Mcauley Dr" "Ashland") )
jp_wikiwiki_aiou_Csv_toMapList
(letseq ( (inputPort (infile "Presidents.csv")) (mapList (jp_wikiwiki_aiou_Csv_toMapList inputPort)) ) (close inputPort) mapList ) → ( (("name" "LINCOLN, Abraham") ("company" "Benton, John B Jr") ("address" "6649 N Blue Gum St") ("city" "New Orleans")) (("name" "CARTER, Jimmy") ("company" "Chanay, Jeffrey A Esq") ("address" "4 B Blue Ridge Blvd") ("city" "Brighton")) (("name" "ROOSEVELT, Franklin") ("company" "Chemel, James L Cpa") ("address" "8 W Cerritos Ave #54") ("city" "Bridgeport")) (("name" "BUSH, George") ("company" "Feltz Printing Service") ("address" "639 Main St") ("city" "Anchorage")) (("name" "CLINTON, Bill") ("company" "Printing Dimensions") ("address" "34 Center St") ("city" "Hamilton")) (("name" "OBARAM, Barack") ("company" "Chapman, Ross E Esq") ("address" "3 Mcauley Dr") ("city" "Ashland")) )