Reputation: 109
I am trying to write a code that removes parentheses from each top level element of the list. For example, the input '( (1 2) (3 4) ) will produce '(1 2 3 4) and the input '((x (y)) z) should produce '(x (y) z).
Is there a way to recognize pairs of parentheses? I was thinking I could find pairs of parentheses and remove them, but I'm not sure how to do that and also how to only remove from the top element.
Upvotes: 1
Views: 3904
Reputation: 2789
Without using append
or map
, you can define mutually recursive functions to do what you want, as follows:
(define (unwrap lst)
(if (null? lst)
'()
(my-append (car lst) (cdr lst))))
(define (my-append lhs rhs)
(cond
[(null? lhs)
(unwrap rhs)]
[(pair? lhs)
(cons (car lhs)
(my-append (cdr lhs) rhs))]
[else
(cons lhs (unwrap rhs))]))
For example:
> (unwrap '((1 2) (3 4 (5 (6)))))
'(1 2 3 4 (5 (6)))
> (unwrap '((x (y)) z))
'(x (y) z)
Upvotes: 0
Reputation: 679
The pattern "I am trying to (do something to) each top level element of the list" is a sure sign that map
will be involved. Also, one big clue is in your first example case:
'((1 2) (3 4)) => '(1 2 3 4)
That's just append*
!
(append* '((1 2) (3 4))) => '(1 2 3 4)
But that's not the case for '((x (y)) z) => '(x (y) z)
.
(append* '((x (y)) z)) => '(x (y) . z)
If you think about it, append*
is very close to what you want: it unwraps one level of parens from each element in a list. Problem is, some of the elements in your input aren't lists, so there's nothing to unwrap.
We could fix that by just wrapping each non-list element in a singleton list, so that '((x (y)) z)
becomes '((x (y)) (z))
. And then we can use append*
:
(append* '((x (y)) (z))) => '(x (y) z)
This is where map
comes handy. map
is a function that takes a function (f
) and a list (lst
) and returns a new list made by applying f
to each element of lst
. For example:
(map symbol? '(a 2 b c 5)) => '(#t #f #t #t #f)
Suppose you wrote a function that takes one argument and either returns it unaltered if it's a list, or else wraps it up as a singleton list if it's not. Let's call it maybe-wrap
. Then you could map maybe-wrap
over your input, and the result could be passed to append*
:
(define (remove-parens lst)
(append* (map maybe-wrap lst)))
I'll leave it to you to write maybe-wrap
.
Upvotes: 2