dionysosz
dionysosz

Reputation: 173

return element from a list that are not included to another list

Hi I want to write a simple function that take 2 lists and returns the elements from the first list that are not included to the other list.

For example l1 '( 1 2 3 4) l2 '( 5 6 2 8 3)

the return should be '( 1 4)

Currently, I have this code:

(define (iteration2)
    (define listA '())
    (for ([list1 a])
        (for ([list2 b])
          (if (equal? list1 list2)
              '()
              (cons list1 listA))))
    listA) 

thanks

Upvotes: 0

Views: 143

Answers (2)

uselpa
uselpa

Reputation: 18927

Before writing a loop (or recursing), it's always advisable to see if one of the build-in functions can do the looping for you. In your case, you want to filter a list, so:

(define (first-not-second l1 l2)
  (filter 
   (lambda (x) (not (member x l2))) 
   l1))

such as

(first-not-second '(1 2 3 4) '(5 6 2 8 3))
=> '(1 4)

The Racket forversion would be

(define (first-not-second l1 l2)
  (for/list ((x l1) #:unless (member x l2))
    x))

and the classical "helper function style" gives

(define (first-not-second l1 l2)

  (define (first-not-second-helper l1 l2)
    (if (empty? l1)
        '()
        (let ((x (car l1)))
          (if (member x l2)
              (first-not-second-helper (cdr l1) l2)
              (cons x (first-not-second-helper (cdr l1) l2))))))

  (first-not-second-helper l1 l2))

In any case, you don't need to loop over the second list because you can use the build-in member procedure.

Upvotes: 2

Óscar López
Óscar López

Reputation: 236094

The procedure performs a list difference operation, it's useful to think of this as a set difference. The trick is to use the member to determine if an element is in a list. I'll not spoil the fun for you by giving a straight answer, just fill-in the blanks in this skeleton of a solution:

(define (diff l1 l2)
  (cond (<???>  ; if the 1st list is empty
         <???>) ; then we're done building the answer, return the empty list
        (<???>  ; if the 1st list's current element is not a member of 2nd list
         (cons <???>             ; then cons the 1st list's current element
               (diff <???> l2))) ; and advance the recursion
        (else                    ; otherwise
         (diff <???> l2))))      ; just advance the recursion

Notice that we only traverse the first list, the second list remains constant through the iteration.

Upvotes: 1

Related Questions