|
|
|
|
|
by shiro
3571 days ago
|
|
I use CL/Scheme/Clojure at work. I generally prefer comprehension style ('for' in Clojure, srfi-42 in Scheme) but sometimes CL's loop let me save a few nestings. One of such patterns is when I have to accumulate multiple kind of things while I zip through the input. Somewhat contrived example: You have a hashtable that maps integer key to a list of strings. You want to scan it just once and build two lists, strings associated with odd keys and strings associated with even keys. ;; populate input
(defvar input (make-hash-table :test 'eql))
(setf (gethash 1 input) '("ichi" "hi"))
(setf (gethash 2 input) '("ni" "fu"))
(setf (gethash 3 input) '("san" "mi"))
(setf (gethash 4 input) '("yon" "shi" "yo"))
(setf (gethash 5 input) '("go" "itsu"))
;; loop
(loop for k being each hash-key in input
when (oddp k) append (gethash k input) into odds
when (evenp k) append (gethash k input) into evens
finally (return (values odds evens)))
; => ("go" "itsu" "san" "mi" "ichi" "hi") and ("yon" "shi" "yo" "ni" "fu")
|
|
1. You could add "using (hash-value v)" in the iteration clause to directly have the value (no gethash).
2. There is maphash too.