Archive for 2010年10月6日|Daily archive page

行列の挿入と削除

 行列(入れ子のリスト)の挿入と削除を考えます。
 先ずは削除、

(define (delete-row lst (pos -1))
  (if lst (pop lst pos))
  lst)

 pop だけでも良いのですが、非破壊にしたかったので。
 そして、挿入

(define (insert-row (lst pos (item '()))
  (let (len (length (lst 0)))
    (push (apply append (dup (list item) len)) lst pos)))

 item をわざわざ list しているのは、空リスト '() や空文字列 ""item に使いたいからです。
 今さら何故、こんなことを?
 それは、次の関数を見ればわかるかも、

(define (delete-end-null-row lsts)  
  (while (and lsts (for-all (fn (x) (and (or (list? x) (string? x)) (empty? x))) (lsts -1)))
    (pop lsts -1))
  lsts)

 動作させてみましょう。

> (setq lsts '(("" "1" "")("2" "" "")(() () ())("" "" "")))
(("" "1" "") ("2" "" "") (() () ()) ("" "" ""))
> (delete-end-null-row lsts)
(("" "1" "") ("2" "" ""))
> 

 こんな感じで、空文字列か空リストだけの行を後ろから削除します。
 後は、列の削除関数を、、、作りません(笑)。
 こうすれば良いからです。

> (transpose (delete-end-null-row (transpose lsts)))
(("" "1") ("2" "") (() ()) ("" ""))
> 

 前述の delete-rowinsert-row も同様です。
 さて、行と列を合わせて、

> (delete-end-null-row (transpose (delete-end-null-row (transpose lsts))))
(("" "1") ("2" ""))
> 

 ちなみに、

> (setq lsts '(("" "1" "")("2" "" "")(() nil ())("" "" "")))
(("" "1" "") ("2" "" "") (() nil ()) ("" "" ""))
> (delete-end-null-row (transpose (delete-end-null-row (transpose lsts))))
(("" "1") ("2" "") (() nil))
> 

 nil は、削除しません。データかもしれませんからね(笑)。
 さて、何故これらの関数を作ったのか?
 gs:table のテーブルから取得したデータを編集するためです。
 gs:table-get は、全テーブル・データをリスト化します。
 保存する際に、後の空文字列だけのリストは不要でしょう?
 そして、delete-rowinsert-row は、もちろん、行や列の挿入/削除用です。
 さあ、これで CSV ViwerCSV Editor にするための準備は、整った?

 以上、如何でしょうか?