/ 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.
Expand |
Embed | Plain Text
; The original one (defn filter-collecting [predicate collector & lists] (lazy-seq (loop [lists lists out []] (if (empty? (first lists)) (reverse out) (let [heads (map first lists)] (if (apply predicate heads) (recur (map rest lists) (cons (apply collector heads) out)) (recur (map rest lists) out))))))) ; My solution starts here (defn nth-tuple [i lists] (map #(nth % i) lists)) (defn create-tuples [lists] (for [i (range (count (first lists)))] (nth-tuple i lists))) (defn filter-elements [pred lists] (let [tuples (create-tuples lists)] (filter #(apply pred %) tuples))) (defn filter-collecting-2 [predicate collector & lists] (let [matching-tuples (filter-elements predicate lists)] (map #(apply collector %) matching-tuples))) ; Usage user=> (filter-collecting-2 (fn [x y] (< x y)) (fn [x y] (+ x y)) '(1 2 32 6) '(3 4 3 7)) (4 6 13) ; An even cleaner solution (see http://gist.github.com/raw/169171/6476ff84d7dbb351910ed428af0352f883c9e5dc/filter-collecting.clj) ;; this one looks much cleaner, but it holds onto the heads of the lists (defn filter-collecting [predicate collector & lists] (let [tuples (apply map vector lists) filtered (filter #(apply predicate %) tuples)] (map #(apply collector %) filtered))) ;; less garbage, but uglier (defn filter-collecting [predicate collector & lists] (map #(apply collector %) (filter #(apply predicate %) (apply map vector lists))))
You need to login to post a comment.
