Reputation: 13
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
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
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
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