keep

added
1.2

ns
clojure.core

type
function

(keep f) (keep f coll)

Returns a lazy sequence of the non-nil results of (f item). Note,
this means false return values will be included.  f must be free of
side-effects.  Returns a transducer when no collection is provided.

                (keep even? (range 1 10))
;;=> (false true false true false true false true false)

            
                ;; comparisons among keep, filter, map and for.

(keep #(if (odd? %) %) (range 10))
;;=> (1 3 5 7 9)

(map #(if (odd? %) %) (range 10))
;;=> (nil 1 nil 3 nil 5 nil 7 nil 9)

(for [ x (range 10) :when (odd? x)] x)
;;=> (1 3 5 7 9)

(filter odd? (range 10))
;;=> (1 3 5 7 9)
            
                ;; Sieve of Eratosthenes by using 'keep'.

(defn keep-mcdr [f coll]
  (lazy-seq
     (when-let [x (first coll)]
       (cons x  (keep-mcdr f (f x (rest coll)))))))

(defn prime-number [n]
  (cons 1
\t(keep-mcdr
\t (fn[x xs] (if (not-empty xs)
\t\t     (keep #(if-not (zero? (rem % x)) %)
\t\t\t   xs)))
\t (range 2 n))))

(prime-number 100)
;;=> (1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97)

            
                (keep seq [() [] '(1 2 3) [:a :b] nil])
;;=> ((1 2 3) (:a :b))
            
                ;; `keep` is useful with maps:

(keep {:a 1, :b 2, :c 3} [:a :b :d])
;;=> (1 2)

            
                ;; A set will work as a predicate for another set.
(keep #{0 1 2 3} #{2 3 4 5})
;;=> (3 2)
            
                ;; keep returns the results of predicates, 
;; filter returns the original values of collection

(keep (fn [[k _]] (#{:a :b} k)) {:a 1 :b 2 :c 3})
;;=> (:a :b)

(filter (fn [[k _]] (#{:a :b} k)) {:a 1 :b 2 :c 3})
;;=> ([:a 1] [:b 2])