Friday, 15 April 2011

lisp - Replace elements in nested quoted lists adds new elements? -



lisp - Replace elements in nested quoted lists adds new elements? -

i have nested list, , trying non-destructively replace elements (inside nested list well). is, given input list

'(1 '(2 3 4) '(5 6 7) 8 9)

i trying achieve

'(0 '(0 0 0) '(0 0 0) 0 0)

i tried following

(defun subs-list (list value) "replaces elements of list of list given value" (loop elt in list collect (if (listp elt) (subs-list elt value) value)))

but when try

(subs-list '(1 '(2 3 4) '(5 6 7) 8 9) 0) (0 (0 (0 0 0)) (0 (0 0 0)) 0 0)

is output get. doing wrong?

mark's answer , wdebeaum's answer explain why you're getting results you're getting; nested quotes mean you've got list (1 (quote (2 3 4)) (quote (5 6 7)) 8 9), , you're replacing symbol quote 0, , that's why (0 (0 (0 0 0)) (0 (0 0 0)) 0 0). want '(1 (2 3 4) (5 6 7) 8 9) no nested quotes.

it's worth pointing out mutual lisp provides functions non-destructively substituting in cons-trees, though: subst, subst-if, , subst-if-not. there destructive versions, too: nsubst, nsubst-if, , nsubst-if-not. in particular, case can replace that's not list 0, either using complement function listp , subst-if, or using listp , subst-if-not:

;; `extra' elements because of quotes: (subst-if-not 0 #'listp '(1 '(2 3 4) '(5 6 7) 8 9)) ;=> (0 (0 (0 0 0)) (0 (0 0 0)) 0 0) (subst-if 0 (complement #'listp) '(1 '(2 3 4) '(5 6 7) 8 9)) ;=> (0 (0 (0 0 0)) (0 (0 0 0)) 0 0) ;; no `extra' elements: (subst-if-not 0 #'listp '(1 (2 3 4) (5 6 7) 8 9)) ;=> (0 (0 0 0) (0 0 0) 0 0) (subst-if 0 (complement #'listp) '(1 (2 3 4) (5 6 7) 8 9)) ;=> (0 (0 0 0) (0 0 0) 0 0)

if wanted take hybrid approach suggested in wdebeaum's answer don't replace quotes, can do:

(subst-if 0 (lambda (x) (not (or (listp x) (eq 'quote x)))) '(1 '(2 3 4) '(5 6 7) 8 9)) ;=> (0 '(0 0 0) '(0 0 0) 0 0) (subst-if-not 0 (lambda (x) (or (listp x) (eq 'quote x))) '(1 '(2 3 4) '(5 6 7) 8 9)) ;=> (0 '(0 0 0) '(0 0 0) 0 0)

lisp common-lisp

No comments:

Post a Comment