Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2009-12-31

KMRCLを眺める (54) PLIST-ALIST

| 01:01 | KMRCLを眺める (54) PLIST-ALIST - わだばLisperになる を含むブックマーク はてなブックマーク - KMRCLを眺める (54) PLIST-ALIST - わだばLisperになる

今回は、KMRCLのlists.lisp中からPLIST-ALISTです。

前回のALIST-PLISTの逆というわけですね。

定義は、

(defun plist-alist (plist)
  (do ((alist '())
       (pl plist (cddr pl)))
      ((null pl) alist)
    (setq alist (acons (car pl) (cadr pl) alist))))

動作は…

(PLIST-ALIST '(A 1 B 2 C 3 D 4 E 5 F 6 G 7))
;⇒ ((G . 7) (F . 6) (E . 5) (D . 4) (C . 3) (B . 2) (A . 1))

あれ、多分期待の結果とは逆になってますよね。

最後にひっくり返さなければいけないんじゃないかと…。うっかりミスでしょうか。

(defun plist-alist (plist)
  (do ((alist '())
       (pl plist (cddr pl)))
      ((null pl) (nreverse alist)) ;逆転
    (setq alist (acons (car pl) (cadr pl) alist))))

ちなみにこういう系統の関数はLOOPだと簡潔に書けることが多いようです。

(DEFUN MY-PLIST-ALIST (PLIST)
  (LOOP :FOR (X Y) :ON PLIST :BY #'CDDR :COLLECT (CONS X Y)))

(MY-PLIST-ALIST '(A 1 B 2 C 3 D 4 E 5 F 6 G 7))
;⇒ ((A . 1) (B . 2) (C . 3) (D . 4) (E . 5) (F . 6) (G . 7))

何故、LOOPで書かないのかを考えてみるに、これまで眺めてきたコードからすると、Kevin Rosenberg氏もPaul Graham氏と同様にLOOPが嫌いなんじゃないかなあと推測しています…。