How to break (11 (12 13)) using Car and Cdr in a circuit

I need to return from the list only those values ​​that are odd, so I'm trying to split my list using the car and cdr functions. I have a recursive call to funciton that checks if Car returns a list and then breaks it with car and cdr, otherwise just pass the first element to the function call if it is odd.

The problem with the special case (10 11 (12 13)) is that the car returns 10 cdr returns (11 (12 13))

then at the second iteration, the car returns (11 (12 13)) cdr returns (11 (12 13))

Since I can smash my list using car and cdr. I need to keep the brackets in my final answer, and also return a list with odd integer values.

+3
source share
3 answers

for a function that should work in an arbitrary nested list. It’s easy for me to first write a version with a flat list (in our case it’s an odd filter), and then edit it to create a nested version (I will call it an odd filter *)

First for a regular odd filter

(define filter-odd
   (lambda (ls)
      (cond
        [(null? ls) '()]
        [(odd? (car ls)) (cons (car ls) (filter-odd (cdr ls)))]
        [else (filter-odd (cdr ls))])))

Now for filter-odd * (one right side will be left as an exercise (although it seems like you know the answer from your question))

(define filter-odd*
   (lambda (ls)
      (cond
        [(null? ls) '()]
        [(list? (car ls)) #| Do something with both car and cdr of ls |# ]
        [(odd? (car ls)) (cons (car ls) (filter-odd* (cdr ls)))]
        [else (filter-odd* (cdr ls))])))

As a note, this design pattern can be used to write any recursive program and convert it from working only with flat lists to work with arbitrarily deep lists.

+4
source

Here's a general solution for lists with an arbitrary level of nesting:

(define (odds-list lst)
  (cond ((null? lst) '())                 ; the list is empty
        ((not (list? (car lst)))          ; first element is not a list
         (if (odd? (car lst))             ; element is odd
             (cons (car lst) (odds-list (cdr lst))) ; build the returned list
             (odds-list (cdr lst))))      ; element is even
        (else (cons (odds-list (car lst)) ; first element is a list
                    (odds-list (cdr lst))))))

, :

:

  • , ,
  • ,
+1

Here is my trick:

(define filter*
  (lambda (e f)
    (cond ((pair? e)
           (append (filter* (car e) f)
                   (filter* (cdr e) f)))
          ((null? e) '())
          ((f e) (list e))
          (else '()))))

and then you can:

> (filter* '(1 (2 . 3) ((4 . 5))) even?)
(2 4)
> (filter* '(1 (2 . 3) ((4 . 5))) odd?)
(1 3 5)
0
source

All Articles