\$\begingroup\$

I tried keeping your approach, although I would've made it an infinite lazy sequence. Yours is probably a better idea, since you still have the infinite sequence (mapping to range as you did) and you can map it to other non-linear sequences too.

(def targets ;; This is more readable for me (sorted-map 3 "fizz", 5 "buzz", 7 "baz")) (defn fizzbuzz [targets n] ;; Pass the targets here! Commas aren't very common in args lists (let [matches (keep (fn [[f w]] ;; Destructuring is nice :P (when (zero? (mod n f)) w)) ;; Got rid of your helper function targets)] ;; ^ Use 'zero?' instead of '(= 0 ...)' (if (empty? matches) ;; Use 'empty?' instead of '(= 0 (count ...))' (str n) (apply str matches)))) ;; I prefer apply here, but seen both ;;;;; EXAMPLE (map (partial fizzbuzz targets) (range 1 20)) => ("1" "2" "fizz" "4" "buzz" "fizz" "baz" "8" "fizz" "buzz" "11" "fizz" "13" "baz" "fizzbuzz" "16" "17" "fizz" "19" "buzz")

There's an even more idiomatic way to rewrite the (if (empty? matches)...) bit:

(if matches (apply str matches) (str n))

Lazy sequence style. Consider fizzbuzz and targets are already defined: