在common-lisp中,如何将元素就地插入到列表中?

时间:2010-12-08 12:46:49

标签: common-lisp

两个问题:

1.我想要一个函数在列表中就地插入一个元素(在任何位置,但列表的开头,请参阅问题2,原因):

CL> (defun insert-in-place (the-list after-position new-element) .... ) => ...
CL> (setf testy-list (list 'a 'b 'c 'd)) => ...  
CL> testy-list => ('A 'B 'C 'D)  
CL> (insert-in-place testy-list 1 'BOOOO) => ...  
CL> testy-list => ('A 'B 'BOOOO 'C 'D)

2.我认为通过函数将元素插入到列表的开头是不可能的,因为args是通过值传递的,所以由于传递了列表的第一个cons单元格,所以它通过值传递它是一个副本,所以改变它的汽车只改变一个复制车,而不是原来的,虽然下面的利弊细胞是共享的,可以改变到位。我是对的吗?

2 个答案:

答案 0 :(得分:9)

1)这里是:

(defun insert-after (lst index newelt)
  (push newelt (cdr (nthcdr index lst))) 
  lst)
(insert-after '(a c d) 0 'b)   => (A B C D)

2)净细胞的破坏性修饰:

(setf testy-list '(a bar))
(defun modify (list)
  (setf (first list) 'foo))
(modify testy-list)
testy-list   => (FOO BAR)

这将第一个利弊细胞的汽车设置为'foo。

答案 1 :(得分:0)

我为我的一个项目做了这个,处理索引0,如果index大于list的长度,则新项目附加在列表的末尾。请注意,它会创建一个新列表,因此可能不适合您。我包括它希望它对某人有用。

(defun list-insert-at (lst index new-value)
  (let ((retval nil))
    (loop for i from 0 to (- (length lst) 1) do
      (when (= i index)
        (push new-value retval))
      (push (nth i lst) retval))
    (when (>= index (length lst))
      (push new-value retval))
    (nreverse retval)))

CL-USER> test
(1 2 3 4 5)
CL-USER> (list-insert-at test 5 'a)
(1 2 3 4 5 A)
CL-USER> (list-insert-at test 0 'a)
(A 1 2 3 4 5)