Перемещение элементов в общем списке Lisp

Есть ли общая функция Lisp, которая будет заменять два элемента в списке с учетом их индексов и возвращать измененный список?

Ответ 1

Вы можете использовать rotatef:

(rotatef (nth i lst) (nth j lst))

Конечно, индексирование списка может быть дорогостоящим (стоимость O (размер списка)), поэтому, если вы делаете это с любой регулярностью, вы предпочитаете использовать массив:

(rotatef (aref arr i) (aref arr j))

Ответ 2

Я бы не стал индексировать в список дважды, используя nthcdr чтобы получить cdr ячейки cons, содержащий первый элемент, который вы хотите поменять, а затем использовать elt чтобы вывести оставшийся элемент из подписок. Это означает, что вам нужно только индексировать, начиная с главы списка один раз.

 (let ((list-tail (nthcdr i list)))
    (rotatef (car list-tail)
             (elt list-tail (- j i)))
    list)

По крайней мере, с моей точки зрения, это достаточно утомительно, чтобы оправдать функцию.