Search code examples
lispcommon-lispin-place

Mapcar in-place: destructively modify a list of lists


I have a list of lists: (setq xs (list (list 1 2 3) (list 4 5 6) (list 7 8 9))). I want to remove a first element from each list to get ((2 3) (5 6) (8 9)). It's easy to do it non-destructively: (mapcar 'cdr xs). But I want mutate the original list. I tried:

(mapcar (lambda (x) (setf x (cdr x))) xs)
(mapcar (lambda (x) (pop x)) xs)

But it doesn't work. How to change each list of xs variable in-place, without creating any temporary lists, as efficiently as possible?


Solution

  • Use MAP-INTO:

    CL-USER 16 > (let ((s (list (list 1 2 3)
                                (list 4 5 6)
                                (list 7 8 9))))
                   (map-into s #'rest s))
    ((2 3) (5 6) (8 9))