Yamin Momo
Yamin Momo

Reputation: 103

How to prevent void in output of list

When I use when in list, #<void> come out quite often uncessarily. Following are examples for using map and for/list.

;; using map    
(define lst '(0 0 0 1 1 1 2 2 2 3 3))
    (map (lambda (x)
             (when (equal? 2 x)
                 x
                 ))
           lst)   
;; expected => '(2 2 2)
;; output => '(#<void>  #<void>  #<void>  #<void>  #<void>  #<void>
;; 2  2  2  #<void>  #<void>)

;; using for/list
    (define my-list '(0 0 0 1 2 1 2 2 2))
     (for/list ([a (drop-right my-list 1)]
                           [b (cdr lst)]
                           [i (in-naturals)])
                  (when (> a b)
                    (list a b i)))
;; expected => '(2 1 4)
;; output => '(#<void> #<void> #<void> #<void> (2 1 4) #<void> #<void> #<void>)

When I use if condition instead, I don't have anything else to put for #false state. How do I prevent those #<void>?

Upvotes: 0

Views: 1083

Answers (2)

Alexis King
Alexis King

Reputation: 43842

As Renzo mentions, you can use filter if your goal is actually filtering. However, it’s worth also mentioning that you can use for/list for this by using a #:when clause in the loop:

(define lst '(0 0 0 1 1 1 2 2 2 3 3))
(define my-list '(0 0 0 1 2 1 2 2 2))

(for/list ([a (drop-right my-list 1)]
           [b (cdr lst)]
           [i (in-naturals)]
           #:when (> a b))
  (list a b i))

; => '((2 1 4))

Upvotes: 2

Renzo
Renzo

Reputation: 27424

In these cases you should not use map or for/list: they apply the same operation to a list of objects and return a list obtained by consing all the results of the application. So, since when has no alternatives, when the condition is false the result is #<void>.

Use the predefined operator filter instead:

(filter (lambda (x) (equal? x 2)) '(0 0 0 1 2 1 2 2 2))
;; => '(2 2 2 2)

Upvotes: 4

Related Questions