ClojureDocs

Nav

Namespaces

keep

clojure.core

Available since 1.2 (source)
  • (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.
8 Examples
(keep even? (range 1 10))
;;=> (false true false true false true false true false)
;; comparisons among keep, filter, map and for.

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

(map #(when (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
	(keep-mcdr
	 (fn[x xs] (if (not-empty xs)
		     (keep #(if-not (zero? (rem % x)) %)
			   xs)))
	 (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])
;; keep rejects nil from results

(keep #(when (number? %) %) [1 "a" 2 "c"])
;; => (1 2)

(map #(when (number? %) %) [1 "a" 2 "c"])
;; => (1 nil 2 nil)

(remove nil? (map #(when (number? %) %) [1 "a" 2 "c"]))
;; => (1 2)
See Also

Returns a lazy sequence of the non-nil results of (f index item). Note, this means false return va...

Added by SoniaH

Returns a lazy sequence consisting of the result of applying f to the set of first items of each c...

Added by ryo

Returns a lazy sequence of the items in coll for which (pred item) returns logical true. pred must...

Added by ryo

Returns a lazy sequence of the items in coll for which (pred item) returns logical false. pred mus...

Added by MicahElliott
4 Notes
    By , created 10.3 years ago

    Note the difference between filter and keep. filter returns the original items in a collection that satisfy the predicate. keep returns the non-nil results of the given function.

    By , created 10.2 years ago, updated 10.2 years ago

    keep is like a map that filters out nil values produced by f and could be defined as:

    (def my-keep (comp (partial remove nil?) map))
    
    or, perhaps more traditionally:
    (defn my-keep [& args]
      (remove nil? (apply map args)))
    
    By , created 6.8 years ago

    Note that, unlike map, keep doesn’t accept multiple collections:

    (filter identity (map get [{:a 1} {:b 2} {:d 3}] [:a :b :c]))
    ; => (1 2)
    
    (keep get [{:a 1} {:b 2} {:d 3}] [:a :b :c])
    ; => ArityException Wrong number of args (3) passed to: core/keep
    
    By , created 5.1 years ago

    It's useful to consider filter and remove as a pair of complementary/similar functions that both return the original items, whereas keep is rather specialized/different.