Posted By

narkisr on 08/15/09


Tagged

filter collection clojure


Versions (?)

My filter collection solution


 / Published in: Lisp
 

URL: http://blog.fogus.me/2009/08/14/clojure-golf-episode-1/

This is an alternative implementation (an answer) to the one presnented in the above URL.

  1. ; The original one
  2. (defn filter-collecting [predicate collector & lists]
  3. (lazy-seq
  4. (loop [lists lists out []]
  5. (if (empty? (first lists))
  6. (reverse out)
  7. (let [heads (map first lists)]
  8. (if (apply predicate heads)
  9. (recur (map rest lists) (cons (apply collector heads) out))
  10. (recur (map rest lists) out)))))))
  11.  
  12. ; My solution starts here
  13. (defn nth-tuple [i lists]
  14. (map #(nth % i) lists))
  15.  
  16. (defn create-tuples [lists]
  17. (for [i (range (count (first lists)))] (nth-tuple i lists)))
  18.  
  19. (defn filter-elements [pred lists]
  20. (let [tuples (create-tuples lists)]
  21. (filter #(apply pred %) tuples)))
  22.  
  23. (defn filter-collecting-2 [predicate collector & lists]
  24. (let [matching-tuples (filter-elements predicate lists)]
  25. (map #(apply collector %) matching-tuples)))
  26.  
  27. ; Usage
  28. user=> (filter-collecting-2 (fn [x y] (< x y)) (fn [x y] (+ x y)) '(1 2 32 6) '(3 4 3 7))
  29. (4 6 13)
  30.  
  31.  
  32. ; An even cleaner solution (see http://gist.github.com/raw/169171/6476ff84d7dbb351910ed428af0352f883c9e5dc/filter-collecting.clj)
  33. ;; this one looks much cleaner, but it holds onto the heads of the lists
  34. (defn filter-collecting [predicate collector & lists]
  35. (let [tuples (apply map vector lists)
  36. filtered (filter #(apply predicate %) tuples)]
  37. (map #(apply collector %) filtered)))
  38.  
  39. ;; less garbage, but uglier
  40. (defn filter-collecting [predicate collector & lists]
  41. (map #(apply collector %) (filter #(apply predicate %) (apply map vector lists))))

Report this snippet  

You need to login to post a comment.