X-Git-Url: http://git.kpe.io/?a=blobdiff_plain;f=lists.lisp;h=77b6fa52401157e11b78451156903100a4df6775;hb=042a035d9708f98f43b41ac07171ee0570658c8b;hp=a1fd55cf1498367cec2e52f84520620770eda60f;hpb=4a5b626f01db51b02f969adb33ddad6aa9ee303a;p=kmrcl.git diff --git a/lists.lisp b/lists.lisp index a1fd55c..77b6fa5 100644 --- a/lists.lisp +++ b/lists.lisp @@ -7,7 +7,7 @@ ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Apr 2000 ;;;; -;;;; $Id: lists.lisp,v 1.5 2003/06/06 21:59:29 kevin Exp $ +;;;; $Id: lists.lisp,v 1.9 2003/07/31 07:32:11 kevin Exp $ ;;;; ;;;; This file, part of KMRCL, is Copyright (c) 2002 by Kevin M. Rosenberg ;;;; @@ -22,13 +22,20 @@ "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) @@ -126,3 +133,54 @@ (let ((results (car list))) (dolist (elem (cdr list) results) (setq results (append results elem))))) + + +;; alists and plists + +(defun alist-elem-p (elem) + (and (consp elem) (atom (car elem)) (atom (cdr elem)))) + +(defun alistp (alist) + (when (listp alist) + (dolist (elem alist) + (unless (alist-elem-p elem) + (return-from alistp nil))) + t)) + +(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)))))) + +(defun get-alist (key alist &key (test #'eql)) + (cdr (assoc key alist :test test))) + +(defun (setf get-alist) (value key alist &key (test #'eql)) + (update-alist key value alist :test test) + value) + +(defun alist-plist (alist) + (apply #'append (mapcar #'(lambda (x) (list (car x) (cdr x))) alist))) + +(defun plist-alist (plist) + (do ((alist '()) + (pl plist (cddr plist))) + ((null pl) alist) + (setq alist (acons (car pl) (cadr pl) alist)))) + +(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))))))) + +