4

I have been working on the following function flatten and so far have it working for just lists. I was wondering if someone could provide me with some insight on how to get it work with pairs? For example (flatten '(a .a)) would return (a a). Thanks.

(define (flatten list)
   (cond ((null? list) null)
         ((list? (car list)) (append (flatten (car list)) (flatten (cdr list))))
         (else
          (cons (car list) (flatten (cdr list))))))
user1081812
  • 53
  • 1
  • 1
  • 3
  • 4
    Flattening `(a . a)` into `(a a)` just seems wrong, since that really introduces an extra level, not decrease it. – C. K. Young Dec 05 '11 at 15:37

3 Answers3

8

Here's one option:

(define (flatten x)
  (cond ((null? x) '())
        ((pair? x) (append (flatten (car x)) (flatten (cdr x))))
        (else (list x))))
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
4

This does what you want, without requiring append, making it o(n). I walks the list as a tree. Some schemes might throw a stack overflow error if the list is too deeply nested. In guile this is not the case.

I claim no copyright for this code.

(define (flatten lst)
  (let loop ((lst lst) (acc '()))
    (cond
     ((null? lst) acc)
     ((pair? lst) (loop (car lst) (loop (cdr lst) acc)))
     (else (cons lst acc)))))
1
(define (flatten l)
  (cond
    [(empty? l) empty]
    [(list? l)
     (append (flatten (first l))
             (flatten (rest l)))]
    [else (list l)]))
Luqman
  • 1,348
  • 1
  • 9
  • 6