リストの破壊的な操作

g000001さんの所のネタ。
http://cadr.g.hatena.ne.jp/g000001/20090521/1242909362

alistからplistへの破壊的な変換。

やってみたら、とっても直接的になった。

(defun nalist-to-plist (alist)
  (loop for x on alist by #'cddr
     do
       (let* ((cons1 x)
	      (cons2 (car x))
	      (key (car cons2))
	      (elem (cdr cons2))
	      (rest (cdr x)))
	 (setf (car cons1) key
	       (cdr cons1) cons2
	       (car cons2) elem
	       (cdr cons2) rest)))
  alist)

(defun nplist-to-alist (plist)
  (loop for x on plist
     do
       (let* ((cons1 x)
	      (cons2 (cdr x))
	      (key (car cons1))
	      (elem (car cons2))
	      (rest (cdr cons2)))
	 (setf (car cons1) cons2
	       (cdr cons1) rest
	       (car cons2) key
	       (cdr cons2) elem)))
  plist)
		
;; CL-USER> (nplist-to-alist (nalist-to-plist (copy-list '((a . 1) (b . 1)))))
;; ((A . 1) (B . 1))