Archive for 2010年9月28日|Daily archive page

newLISP で CSV を扱う。

 newLISP で CSV(Comma-Separated Values)を扱うなら、ArtfulCodeModule:CSV があります。ArtfulCode の名にふさわしい洗練されたコードです。
 と、言いつつ、今回は、自作します。何故か?それは後ほど。

 まずは、スクリプトから、
(defun は newlisp-utility.lsp に定義してあります。)

(define CRLF "\r\n")
(define regexCRLF "\r*\n")
(defun stringEx (x)
  (if (string? x) (string "\"" x "\"") (string x)))
(defun list2csv (lst)
  (let (csv "")
    (dolist (row lst)
      (extend csv (join (map stringEx row) ",") CRLF))))
(defun string-convert (str) 
  (if (catch (eval-string str) 'res) (if res res str) str))
(defun csv2list (csv)
  (let (lst '())
    (dolist (row (parse (if (ends-with csv regexCRLF 0) (chop csv) csv) regexCRLF 0))
      (push (map string-convert (parse row ",")) lst -1))))

 関数名からわかるように、CSV文字列とリストを相互に変換しますが、これだけです(笑)。
 だから、自作。いえいえ。それは動作させてみれば判ります。
 次のデータは、 Introduction to newLISP に載っていた太陽系惑星のデータを使わせてもらっています。

(setq sol-sys '(("Planet name" "Equator diameter (earth)" "Mass (earth)"
"Orbital radius (AU)" "Orbital period (years)"
"Orbital Incline Angle" "Orbital Eccentricity"
"Rotation (days)" "Moons")
("Mercury" 0.382 0.06 0.387 0.241 7.00 0.206 58.6 0)
("Venus" 0.949 0.82 0.72 0.615 3.39 0.0068 -243 0)
("Earth" 1.00 1.00 1.00 1.00 0.00 0.0167 1.00 1)
("Mars" 0.53 0.11 1.52 1.88 1.85 0.0934 1.03 2)
("Jupiter" 11.2 318 5.20 11.86 1.31 0.0484 0.414 63)
("Saturn" 9.41 95 9.54 29.46 2.48 0.0542 0.426 49)
("Uranus" 3.98 14.6 19.22 84.01 0.77 0.0472 -0.718 27)
("Neptune" 3.81 17.2 30.06 164.8 1.77 0.0086 0.671 13)
("Pluto" 0.18 0.002 39.5 248.5 17.1 0.249 -6.5 3)))

 では動作を、

> (setq csv (list2csv sol-sys))
"\"Planet name\",\"Equator diameter (earth)\",\"Mass (earth)\",\"Orbital radius (AU)\",\"Orbital period (years)\",\"Orbital Incline Angle\",\"Orbital Eccentricity\",\"Rotation (days)\",\"Moons\"\r\n\"Mercury\",0.382,0.06,0.387,0.241,7,0.206,58.6,0\r\n\"Venus\",0.949,0.82,0.72,0.615,3.39,0.0068,-243,0\r\n\"Earth\",1,1,1,1,0,0.0167,1,1\r\n\"Mars\",0.53,0.11,1.52,1.88,1.85,0.0934,1.03,2\r\n\"Jupiter\",11.2,318,5.2,11.86,1.31,0.0484,0.414,63\r\n\"Saturn\",9.41,95,9.54,29.46,2.48,0.0542,0.426,49\r\n\"Uranus\",3.98,14.6,19.22,84.01,0.77,0.0472,-0.718,27\r\n\"Neptune\",3.81,17.2,30.06,164.8,1.77,0.0086,0.671,13\r\n\"Pluto\",0.18,0.002,39.5,248.5,17.1,0.249,-6.5,3\r\n"
> (begin (print csv) nil)
"Planet name","Equator diameter (earth)","Mass (earth)","Orbital radius (AU)","Orbital period (years)","Orbital Incline Angle","Orbital Eccentricity","Rotation (days)","Moons"
"Mercury",0.382,0.06,0.387,0.241,7,0.206,58.6,0
"Venus",0.949,0.82,0.72,0.615,3.39,0.0068,-243,0
"Earth",1,1,1,1,0,0.0167,1,1
"Mars",0.53,0.11,1.52,1.88,1.85,0.0934,1.03,2
"Jupiter",11.2,318,5.2,11.86,1.31,0.0484,0.414,63
"Saturn",9.41,95,9.54,29.46,2.48,0.0542,0.426,49
"Uranus",3.98,14.6,19.22,84.01,0.77,0.0472,-0.718,27
"Neptune",3.81,17.2,30.06,164.8,1.77,0.0086,0.671,13
"Pluto",0.18,0.002,39.5,248.5,17.1,0.249,-6.5,3
nil
> (csv2list csv)
(("Planet name" "Equator diameter (earth)" "Mass (earth)" "Orbital radius (AU)" "Orbital period (years)" 
  "Orbital Incline Angle" "Orbital Eccentricity" "Rotation (days)" "Moons") 
 ("Mercury" 0.382 0.06 0.387 0.241 7 0.206 58.6 0) 
 ("Venus" 0.949 0.82 0.72 0.615 3.39 0.0068 -243 0) 
 ("Earth" 1 1 1 1 0 0.0167 1 1) 
 ("Mars" 0.53 0.11 1.52 1.88 1.85 0.0934 1.03 2) 
 ("Jupiter" 11.2 318 5.2 11.86 1.31 0.0484 0.414 63) 
 ("Saturn" 9.41 95 9.54 29.46 2.48 0.0542 0.426 49) 
 ("Uranus" 3.98 14.6 19.22 84.01 0.77 0.0472 -0.718 27) 
 ("Neptune" 3.81 17.2 30.06 164.8 1.77 0.0086 0.671 13) 
 ("Pluto" 0.18 0.002 39.5 248.5 17.1 0.249 -6.5 3))
> 

 CSV文字列からリストへの変換で、文字列は文字列、数値は数値へと変換されているのに、お気付きでしょうか?これが自作したポイントです。
 これなら、EXCEL で作った表を CSVで保存すれば、newLISP で簡単に扱え、逆も可能です。

 以上、如何でしょうか?

広告