;;;a few functions to facilitate dealing with association lists which have ;;;multiple cdrs for the same car ;;;© 2001 Herman Mayfarth ;;;use at your own risk ;;; ;;;mcdrs ;;;returns a list of cdrs for a given key (defun mcdrs (key alist / out) (foreach n alist (if (eq (car n) key) (setq out (cons (cdr n) out)))) (reverse out) ) ;;;mcdrtwo ;;;returns a list of two lists - first sublist is the cdrs, second sublist ;;;is the position of each cdr in the input list (defun mcdrtwo (key alist / i out pos) (setq i 0) (foreach n alist (progn (setq i (1+ i)) (if (eq (car n) key) (setq out (cons (cdr n) out) pos (cons i pos)) ) );progn ) (mapcar 'reverse (list out pos)) ) ;;;mcdra ;;;returns a list of dotted pairs - the car of each dotted pair is a cdr of ;;;the input, and each cdr is the position of its own car in the input list (defun mcdra (key alist / i out pos) (setq i 0) (foreach n alist (progn (setq i (1+ i)) (if (eq (car n) key) (setq out (cons (cons (cdr n) i) out)) ) );progn ) (reverse out) ) ;;;mcdrpos ;;;returns a list of two element lists - the first element of each list is a ;;;cdr in the input list, and the second element is its position in the input (defun mcdrpos (key alist / i out pos) (setq i 0) (foreach n alist (progn (setq i (1+ i)) (if (eq (car n) key) (setq out (cons (list (cdr n) i) out)) ) );progn ) (reverse out) ) ;;;mcdrsread ;;;***use with caution*** ;;;provided any of input cdrs are strings (which it checks) the return value ;;;is an association list - the car of each dotted pair is a cdr of ;;;the input, *converted to a (global) symbol* by (read)ing a string value, ;;;and each cdr is the position of its own car in the input list (defun mcdrsread (key alist / i out pos) (setq i 0) (foreach n alist (progn (setq i (1+ i)) (if (and (eq (car n) key) (= (type (cdr n)) 'STR)) (setq out (cons (list (read(cdr n)) i) out)) ) );progn ) out ) ;;;mcdrrep ;;;modifies the value of association list alist by replacing ;;;cdrs specified by key with the corresponding value from nvals (defun mcdrrep (key alist nvals / i j la ln out) (setq la (length alist) ln (length nvals) i 0 j 0 out nil) (while (and (< i la) (< j ln)) (if (eq (caar alist) key) (progn (setq out (cons (cons key (nth j nvals)) out)) (setq j (1+ j)) );progn (setq out (cons (car alist) out)) );if (setq alist (cdr alist)) (setq i (1+ i)) );while (if alist (foreach n alist (setq out (cons n out))) ) (reverse out) );mcdrrep