如何从列表中移除第一个元素?

5
如何在Scheme中从列表中删除第一个元素?
假设我有以下列表:
'((apple bob car) (cat dig) (e)))

我该如何仅删除apple并保留其余部分?

4个回答

10

Scheme 中的三个基本列表操作是

  • cdr,意思是“rest”或“给我这个列表,不包括第一个元素”
  • car,意思是“first”或“给我这个列表的第一个元素”
  • cons,意思是追加列表

假设 s 是列表 ((apple bob car) (cat dig) (e)):

中间步骤:

(car s)       ; (apple bob car)
(cdr (car s)) ; (bob car)
(cdr s)       ; ((cat dig) (e))

最终表达式

(cons (cdr (car s))) (cdr s))
结果
((bob car) (cat dig) (e))

5
首先,请认识到您的问题有点不一致。如果想要移除列表中的第一个元素,那么你将会留下:
((cat dig) (e))

因为列表中的第一个元素是(apple bob car)

如果您只想去掉apple,那么如果列表的头部(car)本身是一个列表,则需要用其cdr替换它。我假设您希望这样做无论列表的深度如何都能起作用,因此您需要使用递归方法(与其他答案不同)。

因此,如果第一项是列表,则需要从列表中删除第一项,并将其递归地添加到列表的其余部分中。这似乎可以工作:

(define removeFirst
  (lambda (input)
    (cond
      ((list? (car input)) (cons (removeFirst (car input)) (cdr input)))
      (else (cdr input))
    )
  )
)

> (removeFirst '((apple bob car) (cat dig) (e)))
((bob car) (cat dig) (e))

1
除了其他答案外,你的问题中还涉及到一种变异的味道,Scheme中的列表通常是不可变的,甚至包含在列表中的列表也是如此。这就是为什么所有其他的答案都返回了一个新的列表,而没有你想要摆脱的元素。你可以将一个列表赋给一个变量,然后使用set!将一个不同的列表赋给同一个变量,但你永远无法改变你首先创建的列表。

0

(cdr x)(其中的 'x' 是一个列表)将会返回除了第一个元素以外的所有元素。将其应用于上面的内容的问题是 apple 不是 '((apple bob car) (cat dig) (e))) 中的第一个元素。你提供的是一个由多个列表组成的列表,而外层列表的第一个元素是列表 (apple bob car)

如果你想要仅删除 "apple",你需要弄清楚你所接收到的列表中的第一项是否本身就是一个列表,如果是,则需要递归地创建一个该列表去掉第一项后的列表(提示:使用递归),然后再加上原始列表的剩余部分。如果第一项不是列表,则只需返回列表的剩余部分即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接