Yesterday, Xah Lee put up a post that showed how to reverse arrays and lists in various languages, including Emacs Lisp. His Elisp examples worked only for arrays so I added one for lists in the comments. Later I realized that although it was pretty efficient it wasn’t really a solution because it built a separate list.
Here’s a less efficient method that does do the reverse in-place
(let ((list '(a b c d e f g))) (do ((i 0 (1+ i)) (j (1- (length list)) (1- j))) ((>= i j) list) (rotatef (nth i list) (nth j list))))
If you’re not familiar with (or don’t like) the do
macro, here’s the same strategy rendered with a while
.
(let* ((list '(a b c d e f g)) (l 0) (r (1- (length list)))) (while (< l r) (rotatef (nth l list) (nth r list)) (incf l) (decf r)) list)
We can also use rotatef
to reverse an array
(let ((vec ["a" "b" "c" "d" "e" "f" "g"])) (do ((i 0 (1+ i)) (j (1- (length vec)) (1- j))) ((>= i j) vec) (rotatef (aref vec i) (aref vec j))))
Of course, all this is a bit silly because Elisp already has this covered. The best and fastest way to reverse a list in-place is
(let ((list '(a b c d e f g)))
(nreverse list))