ki.
ki.

Reputation: 35

how to define last in scheme?

how can I write a function to take the last element of the list?

Upvotes: 2

Views: 3580

Answers (8)

snario
snario

Reputation: 473

The best way to get what you want:

(define (last lst)
  (cond [(empty? lst) empty]
        [(empty? (rest lst)) (first lst)]
        [else (last (rest lst))]))

Upvotes: 0

Tom Murphy
Tom Murphy

Reputation: 335

I like short, sweet, fast, tail-recursive procedures.

Named let is my friend.

This solves the original problem and returns #f if the list has no last element.

(define (last L) (let f ((last #f) (L L)) (if (empty? L) last (f (car L) (cdr L)))))

Upvotes: 0

eric.christensen
eric.christensen

Reputation: 3231

(define last
  (lambda (ls)
    (list-ref ls (- (length ls) 1))))

Upvotes: 0

linjunhalida
linjunhalida

Reputation: 4655

find the last of a list:

(define (last l)
    (cond ((null? (cdr l)) (car l))
          (else (last (cdr l)))))

use map to map last to a list:

(map last '((a b) (c d) (e f)))
==> (b d f)

so a new function:

(define (last-list l)
  (map last l)
  )

(last-list '((a b) (c d) (e f)))
==> (b d f)

Upvotes: 5

Vijay Mathew
Vijay Mathew

Reputation: 27174

May not be the most efficient, but certainly one of the simplest:

(define (last lst)
  (car (reverse lst)))

Examples:

(last '(1 2 3 4)) => 4    
(last '((a b) (b c) (d e))) => (d e)

Upvotes: 4

Jerry Coffin
Jerry Coffin

Reputation: 490108

Yet another possibility:

(define (last thelist) 
    (if 
        (null? (cdr thelist)) (car thelist)
        (last (cdr thelist))))

(define (all-last lists) (map last lists))

Edit: just saw that you don't know map, and want a solution without it:

(define (all-last lists) 
    (if
        (null? lists) `()
        (cons (last (car lists)) (all-last (cdr lists)))))

As far as getting an empty list goes, I'd guess you're trying to use this map-like front-end with your original definition of last, whereas it's intended to work with the definition of last I gave above. Try the following definitions:

(define (last thelist) (if 
                 (null? (cdr thelist)) (car thelist)
                 (last (cdr thelist))))

(define (all-last lists) (if
                      (null? lists) `()
                      (cons (last (car lists)) (all-last (cdr lists)))))

and running a quick test:

(all-last `((a b) (c d) (e f)))

The result should be:

(b d f)

Upvotes: 1

McPherrinM
McPherrinM

Reputation: 4594

Your last function is good, but you have to think about what you want to do with it now.

You have a list of lists, and you want to take the last of all those.

So recurse down your list applying it each time:

(define (answer lst)
   (cond ((null? (cdr l)) null)
         (else (cons (last (car l)) (answer (cdr lst))))

Upvotes: 1

Steven Schlansker
Steven Schlansker

Reputation: 38526

The code you've written - to take the last element of a list - is correctly returning the last element of the list. You have a list of lists. There is an outer list

(x y z)

where

x = (a b)
y = (c d)
z = (e f)

So you're getting the last element of the list, z, which is (e f)

Did you want your last function to do something different? If you want it to return the last element of the last nested list, you need to change your base case. Right now you return the car. Instead, you want to check if the car is a list and then call your nested-last function on that.

Make sense?

Upvotes: 3

Related Questions