Common Lisp:如何在没有给定列表的第n个元素的情况下返回列表?

use*_*236 6 lisp common-lisp

我有一个问题,如何返回没有给定列表的第n个元素的列表?例如,给定列表:(1 2 3 2 4 6)和给定n = 4,在这种情况下,返回列表应该是(1 2 3 4 6).

Sam*_*ard 8

一个简单的递归解决方案:

(defun remove-nth (n list)
  (declare
    (type (integer 0) n)
    (type list list))
  (if (or (zerop n) (null list))
    (cdr list)
    (cons (car list) (remove-nth (1- n) (cdr list)))))
Run Code Online (Sandbox Code Playgroud)

这将共享公共尾部,除非列表具有n或多个元素,在这种情况下,它返回一个新列表,其中包含与提供的元素相同的元素.

  • @ 6502,原始问题没有说明是否禁止修改输入列表或者输出列表是否应该共享结构.我通常更喜欢我的功能是非破坏性和共享结构,但我没有在禁止修改输入的问题中看到任何内容.C和Java程序员可能会发现这是一件很自然的事情.在某些情况下,共享尾部可能是负债而不是资产. (2认同)

dan*_*lei 7

使用remove-if:

(defun foo (n list)
  (remove-if (constantly t) list :start (1- n) :count 1))
Run Code Online (Sandbox Code Playgroud)

butlast/ nthcdr解决方案(更正):

(defun foo (n list)
  (append (butlast list (1+ (- (length list) n))) (nthcdr n list)))
Run Code Online (Sandbox Code Playgroud)

或者,可能更具可读性:

(defun foo (n list)
  (append (subseq list 0 (1- n)) (nthcdr n list)))
Run Code Online (Sandbox Code Playgroud)

使用loop:

(defun foo (n list)
  (loop for elt in list
        for i from 1
        unless (= i n) collect elt))
Run Code Online (Sandbox Code Playgroud)