8

私は elisp で独自のディープ コピー ルーチンを実装しようとしています (のような(setq newlist oldlist)ものは単なる浅いコピーを提供するように見え、(copy-sequence newlist oldlist)それでもnewlistの要素の変更にさらされたままになるためoldlist)

さらに、私が望むことを行う機能があれば、それを見つけることができません。

私の関数の定義は次のとおりです。

(defun deep-copy (iList oList)

    (setq oList (car iList))
    (setq counter (- (length iList) 1))
    (setq iList (cdr iList))
    (while (> counter 0)
        (setq oList (cons oList (car iList)))
        (setq iList (cdr iList))
        (setq counter (- counter 1) )))

そしてその後、たまたまあるのiListは次のとおりです。 つまり、ネストされたリストです。(1 2 3 4 5 6)oList(((((1 . 2) . 3) . 4) . 5) . 6)

引用、逆引用、追加の使用、oList(car iList)inの順序の切り替え(cons # #)、解決策のグーグル検索を試みましたが、運がありません (エラーまたはガベージ)。

コードに弱点がある場合 (私は elisp 初心者です)、既存のリストに要素を適切にコンスする方法を教えてもらえますか?

例は、次の形式のバリアントになる傾向があります(cons 'pine '(fir oak maple))。ここ'(fir oak maple)で、ハードコードされたリスト

編集: 過去 2 時間、私は自分自身と戦ってきました (呼び出し関数で oList をコメントアウトし、古いバージョンを参照し続けたため)。いずれにせよ、スワップoList(car iList)てから最後に反転することでうまくいくようです(しかし、もっと良い方法があるはずです!?)。

(defun deep-copy (iList)
  (setq oList nil )
  (setq counter (- (length iList) 1))
  (while (>= counter 0)
    (setq oList (cons (car iList) oList) )
    (setq iList (cdr iList) )
    (setq counter (- counter 1) ))
  (reverse oList)
    )
4

2 に答える 2

12

Elispには機能がありますcopy-tree。の再帰バージョンですcopy-sequence:

(let* ((orig '((1 2) (3 4)))
       (copy (copy-tree orig)))
  (setcdr (cadr copy) '(0))
  (list orig copy))
==> (((1 2) (3 4)) ((1 2) (3 0)))

あなたの場合、次のように書くことができます:

(setq oList (copy-tree iList))
于 2013-06-02T19:58:51.463 に答える