r10151: updates
[kmrcl.git] / lists.lisp
index 674a5d76b22d9977aff797b61e0d71d1b55d73bd..dfa9d386d25d5c9f100c317372442b3ef15adcff 100644 (file)
@@ -7,7 +7,7 @@
 ;;;; Programmer:    Kevin M. Rosenberg
 ;;;; Date Started:  Apr 2000
 ;;;;
 ;;;; Programmer:    Kevin M. Rosenberg
 ;;;; Date Started:  Apr 2000
 ;;;;
-;;;; $Id: lists.lisp,v 1.10 2003/08/12 06:37:53 kevin Exp $
+;;;; $Id$
 ;;;;
 ;;;; This file, part of KMRCL, is Copyright (c) 2002 by Kevin M. Rosenberg
 ;;;;
 ;;;;
 ;;;; This file, part of KMRCL, is Copyright (c) 2002 by Kevin M. Rosenberg
 ;;;;
     (unless (find elem l1)
       (setq l1 (append l1 (list elem))))))
 
     (unless (find elem l1)
       (setq l1 (append l1 (list elem))))))
 
-(defun remove-from-tree-if (pred tree)
+(defun remove-from-tree-if (pred tree &optional atom-processor)
   "Strip from tree of atoms that satistify predicate"
   (if (atom tree)
       (unless (funcall pred tree)
   "Strip from tree of atoms that satistify predicate"
   (if (atom tree)
       (unless (funcall pred tree)
-       tree)
-    (let ((car-strip (remove-from-tree-if pred (car tree)))
-         (cdr-strip (remove-from-tree-if pred (cdr tree))))
+       (if atom-processor
+           (funcall atom-processor tree)
+         tree))
+    (let ((car-strip (remove-from-tree-if pred (car tree) atom-processor))
+         (cdr-strip (remove-from-tree-if pred (cdr tree) atom-processor)))
       (cond
        ((and car-strip (atom (cadr tree)) (null cdr-strip))
        (list car-strip))
       (cond
        ((and car-strip (atom (cadr tree)) (null cdr-strip))
        (list car-strip))
 
 (defmacro update-alist (akey value alist &key (test '#'eql) (key '#'identity))
   "Macro to support below (setf get-alist)"
 
 (defmacro update-alist (akey value alist &key (test '#'eql) (key '#'identity))
   "Macro to support below (setf get-alist)"
-  (let ((elem (gensym)))
-    `(let ((,elem (assoc ,akey ,alist :test ,test :key ,key)))
-       (if ,elem
-          (progn
-            (setf (cdr ,elem) ,value)
-            ,alist)
-       (setf ,alist (acons ,akey ,value ,alist))))))
+  (let ((elem (gensym "ELEM-"))
+       (val (gensym "VAL-")))
+    `(let ((,elem (assoc ,akey ,alist :test ,test :key ,key))
+          (,val ,value))
+       (cond
+       (,elem
+        (setf (cdr ,elem) ,val))
+       (,alist
+        (setf (cdr (last ,alist)) (list (cons ,akey ,val))))
+        (t
+         (setf ,alist (list (cons ,akey ,val)))))
+       ,alist)))
 
 (defun get-alist (key alist &key (test #'eql))
   (cdr (assoc key alist :test test)))
 
 (defun (setf get-alist) (value key alist &key (test #'eql))
 
 (defun get-alist (key alist &key (test #'eql))
   (cdr (assoc key alist :test test)))
 
 (defun (setf get-alist) (value key alist &key (test #'eql))
+  "This won't work if the alist is NIL."
   (update-alist key value alist :test test)
   value)
 
   (update-alist key value alist :test test)
   value)
 
 
 (defun plist-alist (plist)
   (do ((alist '())
 
 (defun plist-alist (plist)
   (do ((alist '())
-       (pl plist (cddr plist)))
+       (pl plist (cddr pl)))
       ((null pl) alist)
     (setq alist (acons (car pl) (cadr pl) alist))))
 
       ((null pl) alist)
     (setq alist (acons (car pl) (cadr pl) alist))))
 
         (setf ,plist (append ,plist (list ,pkey ,value)))))))
 
 
         (setf ,plist (append ,plist (list ,pkey ,value)))))))
 
 
+(defun unique-slot-values (list slot &key (test 'eql))
+  (let ((uniq '()))
+    (dolist (item list (nreverse uniq))
+      (let ((value (slot-value item slot)))
+       (unless (find value uniq :test test)
+         (push value uniq))))))
+
+
+