[racket] for/hash and for/list: adding nothing, adding more than one thing
To skip iterations, you want to use the #:when or #:unless for-clauses. In your first example, you should write
(for/list ([i '(1 2 3 4 5)]
#:when (even? i))
(* i 100))
Your second wish is less doable in the current state of things. I have a library on github [1] that allows you to extend for/fold with arbitrary accumulation styles, so you can easily write a style that adds several items if there are several (or always several).
To add several elements to an accumulated hash, you have several options to represent the multitude of key/value pairs you wish to add. Let's just say the body of your loop produces a list of key/value pairs.
You would then write (I'm going to give arbitrary keys, since you provided none)
(define-accumulator hash*
[h #:initial #hash()
#:bind alst
#:inner (for/fold ([h h]) ([kv (in-list alst)])
(hash-set h (car kv) (cdr kv)))])
(for/accumulate ([h #:type hash*]) ([i '(1 2 3 4 5)])
(list (cons i (* i 100)) (cons (- i) (* i 200))))
[1] https://github.com/ianj/nifty-macros
Disclaimer: this library does not bind defined accumulators so that you can attach accumulator styles to existing bindings. In this case if you want to provide hash*, you should write
(define-syntax (hash* stx) (raise-syntax-error #f "For use in for/accumulate" stx))
-Ian
----- Original Message -----
From: "Tim Nelson" <tbnelson at gmail.com>
To: "users" <users at racket-lang.org>
Sent: Thursday, March 21, 2013 6:55:35 PM GMT -05:00 US/Canada Eastern
Subject: [racket] for/hash and for/list: adding nothing, adding more than one thing
Dear All,
I've recently started hacking Racket again, and am loving the for/* constructs.
Awesome stuff. However, I have two questions about for/hash.
(1) How can I *not* add a hash entry for a given iteration?
When I use for/list, can I abuse the nature of empty and append* (I cringe as I write this):
(append* (for/list ([i '(1 2 3 4 5)])
(cond [(even? i) (list (* i 100))]
[else empty])))
Surely there is a better way to do this for for/list, and a way in general for for/hash?
(2) How can I add multiple entries (that is, >1 key-value pair) in a given iteration?
Again, using for/list I can cheat via append*:
(append* (for/list ([i '(1 2 3 4 5)])
(list (* i 100) (* i 200))))
What's the right way to do this in for/hash?
Thanks,
- Tim
____________________
Racket Users list:
http://lists.racket-lang.org/users