2010-12-08 8 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. argsに値が渡されるため、リストの最初のコンスセルが渡されるので、関数を介してリストの先頭に要素を挿入することは不可能ですそれはコピーであるため、その車を変更するだけで元のコピーではなく、次のコンスセルが共有され、その場で変更が可能ですが、コピーカーが変更されます。私は正しいですか?

答えて

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) 

これはFOO」に最初のコンスセルの車を設定します。

+0

ありがとうございます。質問2について:修正するために正確に渡されているものを呼び出すと(テストリストを修正する)テストリストの第1コンスセルを値またはリファレンスとして使用するか?私は正しいとは言えませんが、質問2についての私の議論の欠陥を見つけることはできません... – Paralife

+0

また私は自分自身でこれをやりました: (rplacd(nthcdr position lst)(cons elem(nthcdr(+ 1位)lst)))) しかしあなたの方が良いです。 実際には、nthcdrを設定したかったのですが、私が使用しているclispでは、nthcdrは設定できません。私はそれがsetfableにする価値があるのだろうかと思う。私の他の質問を参照してください:http://stackoverflow.com/questions/4387967/does-a-setfable-nthcdr-implementation-exist – Paralife

+0

質問2について:あなたが(testyリストを変更する)を呼び出すと、コンスセル自体を渡します( "参照によって")。 – koddo

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) 
関連する問題