;;;; 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
;;;;
(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)
- 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))
(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))
+ "This won't work if the alist is NIL."
(update-alist key value alist :test test)
value)
(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))))
(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))))))
+
+
+