Reputation: 51
I'm trying to design a function called changeList that modifies a list in scheme.
The function should drop each number between -1 and +1 inclusive. For each number greater than 1 it should replace the number with 10 times the number. For each number smaller than -1 it should replace the number with the absolute value of the reciprocal.
Here's the code I have so far
(define (changeList x)
(map (lambda (x)
(if (> x 1) (* x 10)
(* (/ 1 x) -1))) x))
Here's an example of the desired output
(changeList '(0 -2 3 -4 1))
-> '( 1/2 30 1/4 )
I'm able to evaluate if x if greater than 1 and if x is smaller than -1, however I'm having issues adding the conditional statements to evaluate if the value is between -1 and 1 inclusively. I need to skip that value and not output it which I'm not sure how to do it.
Upvotes: 1
Views: 537
Reputation: 236170
It'd be better if first we get rid of the numbers in the range [-1, 1]
: that's where filter
will come in handy. After that, we can apply map
to the result of the filtering step, implementing the required rules. This should do the trick:
(define (changeList lst)
(map (λ (x) (if (> x 1) (* 10 x) (/ -1 x)))
(filter (λ (x) (or (< x -1) (> x 1)))
lst)))
In Racket we can do the filter-then-map idiom in a single step, and it'll also be more efficient:
(define (changeList lst)
(filter-map (λ (x) (and (or (< x -1) (> x 1))
(if (> x 1) (* 10 x) (/ -1 x))))
lst))
Either way, it works as expected:
(changeList '(0 -2 3 -4 1))
=> '(1/2 30 1/4)
Upvotes: 1
Reputation: 10163
In common lisp, one would use mapcan
, which is append-map
in Racket.
The results returned by the function given to append-map
must return a list or '()
.
(define (changeList lst)
(append-map (lambda (x)
(cond ((> x 1) (list (* x 10)))
((< x -1) (list (* (/ 1 x) -1)))
(else '())))
lst))
Always, if you want to use a map
but sometimes no results should be collected,
you can use append-map
and use '()
as return value everywhere nothing should
be collected.
Upvotes: 0