リストの破壊的操作
リストの破壊的操作をする - 象徴ヶ淵 経由http://cadr.g.hatena.ne.jp/g000001/20090521/1242909362 の問題
nalist-to-plist
(nalist-to-plist '((foo . 1) (bar . 2) (baz . 3))) => (foo 1 bar 2 baz 3)
らしい。(key1 value1 key2 value2 ...) という list を plist と呼ぶことをはじめて知った。最初は (get 'symbol 'property-name) のことかと思った。
そもそも、これを読んで「へぇーへぇーへぇー」とか言ってた。
alist 例.((foo . 1) (bar .2) ...)とplist 例.(foo 1 bar 2 ....)の使うコンスセル数は同じことが知られています。
http://cadr.g.hatena.ne.jp/g000001/20090521/1242909362
手動で展開(?)してみると確かに同じだ。へぇーへぇーへぇー。
((foo . 1) . ((bar . 2) . nil)) ;4こ (foo . (1 . (bar . (2 . nil)))) ;4こ
んで、40分ほどかかってできたのがこれ。
(defun nalist-to-plist (alist) (if (null alist) nil (let ((car (car alist)) (cdr (cdr alist))) (setf (car alist) (car car) (cdr alist) car (car car) (cdr car) (cdr car) (nalist-to-plist cdr)) alist))) => nalist-to-plist (nalist-to-plist '((foo . 1) (bar . 2) (baz . 3))) => (foo 1 bar 2 baz 3)
nplist-to-alist
こっちは7分くらいでできた。
(defun nplist-to-alist (plist) (if (null plist) nil (let ((cadr (cadr plist)) (cdr (cdr plist))) (setf (car cdr) plist (cdr plist) cadr (cdr cdr) (nplist-to-alist (cdr cdr))) cdr))) => nplist-to-alist (nplist-to-alist '(foo 1 bar 2 baz 3)) => ((foo . 1) (bar . 2) (baz . 3))
説明はしない(ぇー