【发布时间】:2010-03-19 22:17:36
【问题描述】:
如何在 Scheme 中从列表中删除第一个元素?
假设我有以下列表
'((apple bob car) (cat dig) (e)))
我怎样才能摆脱 apple 并留下其余部分?
【问题讨论】:
如何在 Scheme 中从列表中删除第一个元素?
假设我有以下列表
'((apple bob car) (cat dig) (e)))
我怎样才能摆脱 apple 并留下其余部分?
【问题讨论】:
Scheme 中三个基本的列表操作是
cdr,意思是“休息”或“给我清单,没有第一项”car,表示“第一个”或“给我列表中的第一个项目”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))
【讨论】:
首先,请认识到您的问题有点前后矛盾。如果你想删除列表中的第一个元素,你会留下
((cat dig) (e))
因为列表中的第一个元素是(apple bob car)。
如果您只是想摆脱apple,那么如果列表的头部(汽车)本身是一个列表,您想用它的 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))
【讨论】:
除了其他答案之外,您的问题还有一种变化的味道,Scheme 中的列表通常是不可变的——即使是列表中的列表。这就是为什么所有其他答案都返回了一个没有您想要删除的元素的新列表的原因。您可以将列表分配给变量,然后使用 set 将不同的列表分配给同一变量!但你永远不会改变你最初制作的清单。
【讨论】:
(cdr x)(其中“x”是一个列表)将为您提供除第一个元素之外的所有列表。将其应用于上述内容的问题是apple 不是:'((apple bob car) (cat dig) (e))) 的第一个元素。你给出的是一个列表列表,外层列表的第一个元素是列表(apple bob car)。
要仅删除“apple”,您需要确定您收到的列表中的第一项本身是否是一个列表,如果是,则将包含该列表的列表与删除的第一项放在一起(提示:递归) ,然后是原始列表的其余部分。如果第一项不是列表,则只需返回列表的其余部分。
【讨论】: