如何删除列表的第一个和最后一个元素?

时间:2014-09-19 21:48:58

标签: list scheme racket

我试图删除Racket中列表的第一个和最后一个元素。还有其他方法可以代替:

(cdr (reverse (cdr (reverse my-list))))

2 个答案:

答案 0 :(得分:2)

使用Racket的内置程序,这是一种方法:

(define my-list '(1 2 3 4 5 6 7 8 9 10))

(drop-right (rest my-list) 1)
=> '(2 3 4 5 6 7 8 9)

注意:我们可以使用cdr代替rest,但rest在Racket中更为惯用。对于更通用的解决方案:

; remove `left` number of elements elements from the left side
; and `right` number of elements from the right side of the list
(define (trim lst left right)
  (drop-right (drop lst left) right))

(trim my-list 1 1)
=> '(2 3 4 5 6 7 8 9)

(trim my-list 2 4)
=> '(3 4 5 6)

答案 1 :(得分:0)

您提供的方法使用了一些内存,因为当您再次反转时,它会占用在进程中丢弃的单元格。然而,Óscars解决方案也有利于细胞,所以它可能有助于清晰,它肯定不会更快。

在500万元素列表中,编译时(在我的机器上)大约需要1.6秒,这主要是gc时间。如果你发现你有性能问题并且你正在编写方案(而不是球拍语言),你可以通过一次传递手动尾递归模数缺点得到它快4倍(400ms):

#!r6rs
(import (rnrs)
        (rnrs mutable-pairs))

(define (middle lst)
  (define head (list 1))
  (let loop ((tail head) (lst (cdr lst)))
    (if (and (pair? lst) (pair? (cdr lst)))
        (begin 
          (set-cdr! tail (list (car lst)))
          (loop (cdr tail) (cdr lst)))
        (cdr head))))

正如你所看到的那样,它非常丑陋所以你必须要用更多的性能来代替2个反转和2个cdrs。