2010-12-08 72 views
5

两个问题:在common-lisp中,如何将元素插入到列表中?

1.I想要的功能插入就地列表中的元素(在任意位置,但在列表的开始,见问题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.我认为通过函数在列表的开始处插入一个元素是不可能的,因为这些参数是按值传递的,所以由于列表的第一个cons单元格被传递,所以它是通过值传递的它是一个副本,所以改变它的车只会改变一辆复制车,而不是原来的车,尽管下面的cons单元是共享的,并且可以在原地进行改变。我对么?

回答

8

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) 

这第一cons单元的轿厢设置为“富。

+0

谢谢。关于问题2:当你打电话(修改测试列表)什么是正在传递修改?测试列表的第一个cons单元是值还是参考?我的意思是你回答说我是不正确的,但我无法找到我关于问题2的论点中的缺陷...... – Paralife 2010-12-08 14:22:18

0

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

(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)