Jonathan Redmond
Jonathan Redmond

Reputation: 13

Scheme remove from list

I need to remove a given digit from a list completely. This would be entered: (remove-digit 1 '(1 2 3 '(4556 1)))

I need to return (2 3 (4556)) I can remove from the list with this code:

(define (remove-digit digit list)
  (cond ((null? list) list)
        ((= digit (car list)) (remove-digit digit (cdr list)))
        (else (cons (car list) (remove-digit digit (cdr list))))))

But cannot remove from the lists in lists. Any help greatly appreciated

Upvotes: 1

Views: 1364

Answers (3)

Will Ness
Will Ness

Reputation: 71119

(define (rem-dig n ds)
  (cond
    ((list? ds) 
       (remove-digit n (map (lambda(d)(rem-dig n d)) ds)))
    (else ds)))

Need to replace the equality predicate from number-specific = to the general equal?:

(define (remove-digit digit list)
  (cond ((null? list) list)
        ((equal? digit (car list)) (remove-digit digit (cdr list)))
        (else (cons (car list) (remove-digit digit (cdr list))))))

Testing:

(rem-dig 1 '(1 2 3 (4556 1)))
;Value 13: (2 3 (4556))

If improper, dotted lists are allowed, it should be tweaked,

(define (rem-dig n ds)
  (cond
    ((list? ds) 
       (remove-digit n (map (lambda(d)(rem-dig n d)) ds)))
    ((pair? ds)
       (let* ((x  (last-pair ds))
              (y  (cdr x))
              (z  (set-cdr! x ()))
              (ds (rem-dig n ds))
              (x  (last-pair ds)))
         (if (not (equal? n y))
           (set-cdr! x y))
         ds))
    (else ds)))

Upvotes: 0

Terje D.
Terje D.

Reputation: 6315

You need to add a clause to the cond statement, handling (sub)lists:

(define (remove-digit digit list)
  (cond ((null? list) list)
        ((eqv? digit (car list)) (remove-digit digit (cdr list)))
        ((list? (car list)) (cons (remove-digit digit (car list)) 
                                  (remove-digit digit (cdr list))))
        (else (cons (car list) (remove-digit digit (cdr list))))))

Upvotes: 2

faisal
faisal

Reputation: 1339

change = to equal?

(define (remove-digit digit list)
  (cond ((null? list) list)
        ((equal? digit (car list)) (remove-digit digit (cdr list)))
        (else (cons (car list) (remove-digit digit (cdr list))))))

(display (remove-digit 1 '(1 2 3 (4556 1))))

Upvotes: 0

Related Questions