removing last element of a list(scheme)

anon picture anon · Feb 15, 2011 · Viewed 29.4k times · Source

So I have to remove the last element of a list in scheme.

For example, let's say I have a list (1 2 3 4). I need to return:

(1 2 3)

My idea:

reverse(list)
car(list)
reverse(list)

Is there a reverse function in scheme(racket)?

Answer

John Clements picture John Clements · Feb 15, 2011

You wrote: "reverse, car, reverse". I believe you meant to write "reverse, cdr, reverse". There's nothing wrong with this solution; it's linear in the size of the list, just like any solution to this that uses the standard lists.

As code:

;; all-but-last: return the list, not including the last element
;; list? -> list?
(define (all-but-last l) (reverse (cdr (reverse l))))

If the multiple traversal of the list or the needless construction of another list copy bothers you, you can certainly avoid it, by writing the thing directly.

Given your almost-solution, I'm going to assume that this isn't homework.

Here's what it would look like, in racket:

#lang racket

(require rackunit)

;; all-but-last : return the list, except for the last element
;; non-empty-list? -> list?
(define (all-but-last l)
  (cond [(empty? l) (error 'all-but-last "empty list")]
        [(empty? (rest l)) empty]
        [else (cons (first l) (all-but-last (rest l)))]))

(check-equal? (all-but-last '(3 4 5))
              '(3 4))