I have a list of things (I\'ll call it L), an index(N) and a new thing(NEW). If I want to replace the thing in L at N with NEW, what is the best way to do this? Should I get the
(setf (nth N L) T)
is the clearest, most succinct, and fastest way, if what you want to do is a "destructive" modification, i.e. actually change the existing list. It does not allocate any new memory.
(defun replace-nth-from-list (list n elem)
(cond
((null list) ())
(t (append (subseq list 0 n) elem (subseq list (+ 1 n)(length list))))))
Sounds like you want either rplaca or replace. See http://www.lispworks.com/documentation/HyperSpec/Body/f_rplaca.htm or http://www.lispworks.com/documentation/HyperSpec/Body/f_replac.htm#replace
Use [REPLACE][1] (I use X instead of your T as T is the true value in Lisp):
(replace L (list X) :start1 N)
[1]: http://www.lispworks.com/documentation/HyperSpec/Body/f_replac.htm REPLACE
How often are you going to do this; if you really want an array, you should use an array. Otherwise, yes, a function that makes a new list consisting of a copy of the first N elements, the new element, and the tail will be fine. I don't know of a builtin off the top of my head, but I haven't programmed in Lisp in a while.
Here is a solution in Scheme (because I know that better than Common Lisp, and have an interpreter for checking my work):
(define (replace-nth list n elem)
(cond
((null? list) ())
((eq? n 0) (cons elem (cdr list)))
(#t (cons (car list) (replace-nth (cdr list) (- n 1) elem)))))
hazzen's advice is good (use arrays) since you probably want to do a lot of these destructive updates and lists are very inefficient at random access. The easiest way to do this
(setq A (make-array 5) :initial-contents '(4 3 0 2 1))
(setf (elt 2 A) 'not-a-number)
where A is an array (although elt
works for any sequence).
However, if you must be functional, that is
Then you should use the Common Lisp equivalent of hazzen's code:
(defun replace1 (list n elem)
(cond
((null list) ())
((= n 0) (cons elem list))
(t (cons (car list) (replace1 (cdr list) (1- n) elem)))))
This looks slow because it is, and that's probably why it's not included in the standard.
hazzen's code is the Scheme version, which is useful is that's what you're using.