bullebullebagarn
bullebullebagarn

Reputation: 31

How to remove duplicates from a list which might contain lists in Racket

The code I've written:

 (define (make-list lst)
  (cond [(null? lst) '()]
        [(member (car lst) (cdr lst)) (make-list (cdr L))]
        [else (cons (car lst) (duplicates (cdr lst)))]))

I want (make-list '(a (a b b (c b) 3) 5 5.0 (e s) (s e s))))) to return:

(a (a b (c b) 3) 5 (e s))

But my procedure returns

'((a b b (c b) 3) 5 5.0 (e s) (s e s))

So it doesn't really do anything besides removing the first element, it doesn't go into the nested lists. Any help would be appreciated

Upvotes: 0

Views: 935

Answers (1)

Sylwester
Sylwester

Reputation: 48745

I'm assuming duplicates and L are forgotten rename mistakes. make-list isn't really a good name since it is a well known procedure in the list library of R7RS, originally from SRFI-1 List library. remove-duplicates might be a better fit?

(define (remove-duplicates lst)
  (cond [(null? lst) '()]
        [(member (car lst) (cdr lst))
         (remove-duplicates (cdr lst))]
        [else
         (cons (car lst) (remove-duplicates (cdr lst)))]))

Now this does all the elements in the given list and it only concerns itself with the top level list. sub lists are compared too:

(remove-duplicates '(a (b c) (b c) a))
; ==> ((b c) a)

You need to instead of just making a list with the first element also check if the first element is a list and do remove-duplicates on both parts. Thus you need to do add a term like this:

(define (remove-duplicates lst)
  (cond [(null? lst) '()]
        [(member (car lst) (cdr lst))
         (remove-duplicates (cdr lst))]
        [(list? (car lst)) ; or pair?
         (cons (remove-duplicates (car lst)) 
               (remove-duplicates (cdr lst)))]         
        [else
         (cons (car lst)
               (remove-duplicates (cdr lst)))]))

(remove-duplicates '((a b b a) (a b b a)))
; ==> ((b a))

Upvotes: 1

Related Questions