3

How to change the contents of a list without changing the contents of the origin...

 2 years ago
source link: https://www.codesd.com/item/how-to-change-the-contents-of-a-list-without-changing-the-contents-of-the-original-list.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

How to change the contents of a list without changing the contents of the original list

advertisements

Trying to create a copy of a list. I have used copy-list but this modifies the original list therefore I cannot use copy-list and copy-tree isn't working. Any suggestions would be appreciated

(defun switch-var (var list_a)
 (let ((temp (copy-list list_a)))
 (setf (cdr (assoc var temp)) (not (cdr (assoc var temp))))temp))

For instance in lisp I will create a list then call switch-var

(setf *list_a* '((A NIL) (B T) (C T) (D NIL)))

* (switch-var ’b *list_a*)

;I will get this which is ok
((A NIL) (B NIL) (C T) (D NIL))

;but if i call it again

* (switch-var ’b *list_a*)

;I will get this which is not ok
((A NIL) (B T) (C T) (D NIL))

;so techincally I do not want to modify the original list_a
;in the function I just want to modify the temp


It would be better to use a loop to copy and modify the list in a single pass. Or map, but I prefer loop.

(defparameter *foo* '((a . nil)
                      (b . t)
                      (c . t)
                      (d . nil)))

(defun switch-variable (var list)
  (loop
     for (name . val) in list
     collecting (cons name
                      (if (eql name var)
                          (not val)
                          val))))

(switch-variable 'b *foo*)
;=> ((A) (B) (C . T) (D))
(switch-variable 'b *foo*)
;=> ((A) (B) (C . T) (D))

Using cons cells instead of lists for the variables is more efficient. It won't show the NIL when printing, but that's just visual (the value is still NIL).

Tags lisp

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK