r9652: improve make-url, rename tests
[kmrcl.git] / lists.lisp
index ed2148ee347cba703e88b21cd44a1f400df42288..3115dd5dbe1b99476baf576be214fe4353615686 100644 (file)
@@ -7,7 +7,7 @@
 ;;;; Programmer:    Kevin M. Rosenberg
 ;;;; Date Started:  Apr 2000
 ;;;;
-;;;; $Id: lists.lisp,v 1.6 2003/06/18 17:12:29 kevin Exp $
+;;;; $Id$
 ;;;;
 ;;;; This file, part of KMRCL, is Copyright (c) 2002 by Kevin M. Rosenberg
 ;;;;
   "Make into list if atom"
   (if (listp obj) obj (list obj)))
 
-(defun filter (fn lst)
-  "Filter a list by function, eliminate elements where fn returns nil"
+(defun map-and-remove-nils (fn lst)
+  "mao a list by function, eliminate elements where fn returns nil"
   (let ((acc nil))
     (dolist (x lst (nreverse acc))
       (let ((val (funcall fn x)))
         (when val (push val acc))))))
 
+(defun filter (fn lst)
+  "Filter a list by function, eliminate elements where fn returns nil"
+  (let ((acc nil))
+    (dolist (x lst (nreverse acc))
+      (when (funcall fn x)
+        (push x acc)))))
+
 (defun appendnew (l1 l2)
   "Append two lists, filtering out elem from second list that are already in first list"
   (dolist (elem l2 l1)
     (unless (find elem l1)
       (setq l1 (append l1 (list elem))))))
 
-(defun remove-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-tree-if pred (car tree)))
-         (cdr-strip (remove-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))
           (progn
             (setf (cdr ,elem) ,value)
             ,alist)
-       (setf ,alist (acons ,akey ,value ,alist))))))
+        (setf ,alist (acons ,akey ,value ,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 doesn't work to add a field which alist value is only modified locally"
   (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))))
 
-(defun get-plist (key plist &key (test 'eql) (missing nil))
-  (let-if (pos (member key plist :test test))
-         (cadr pos)
-         missing))
+(defmacro update-plist (pkey value plist &key (test '#'eql))
+  "Macro to support below (setf get-alist)"
+  (let ((pos (gensym)))
+    `(let ((,pos (member ,pkey ,plist :test ,test)))
+       (if ,pos
+          (progn
+            (setf (cadr ,pos) ,value)
+            ,plist)
+        (setf ,plist (append ,plist (list ,pkey ,value)))))))
+
+