更改列表的第n个元素

joh*_*ies 13 lisp common-lisp

我想更改列表的第n个元素并返回一个新列表.

我想到了三个相当不优雅的解决方案:

(defun set-nth1 (list n value)
  (let ((list2 (copy-seq list)))
    (setf (elt list2 n) value)
    list2))

(defun set-nth2 (list n value)
  (concatenate 'list (subseq list 0 n) (list value) (subseq list (1+ n))))

(defun set-nth3 (list n value)
  (substitute value nil list 
    :test #'(lambda (a b) (declare (ignore a b)) t)
    :start n    
    :count 1))
Run Code Online (Sandbox Code Playgroud)

这样做的最佳方式是什么?

hua*_*uan 5

怎么样

(defun set-nth4 (list n val)
  (loop for i from 0 for j in list collect (if (= i n) val j)))
Run Code Online (Sandbox Code Playgroud)

也许我们应该注意到它的相似性substitute并遵循它的惯例:

(defun substitute-nth (val n list)
  (loop for i from 0 for j in list collect (if (= i n) val j)))
Run Code Online (Sandbox Code Playgroud)

顺便说set-nth3一下,有一个功能,不断,完全适合这样的情况:

(defun set-nth3 (list n value)
  (substitute value nil list :test (constantly t) :start n :count 1))
Run Code Online (Sandbox Code Playgroud)

编辑:

另一种可能性

(defun set-nth5 (list n value)
  (fill (copy-seq list) value :start n :end (1+ n)))
Run Code Online (Sandbox Code Playgroud)