The keep
function in Clojure invokes a function on each item in a collection and only returns non-nil results from the function invocation. The result of the keep
function is a lazy sequence.
The following example uses the keep
function, but also show what results would be when using map
function on the same collection with the same function argument:
(ns mrhaki.seq.keep (:require [clojure.test :refer [is]])) (def stuff ["Clojure" "Groovy" "Java"]) ;; Function keep filters on non-nil results that are returned ;; from applying the function. (is (= '("Clojure has more than 6 characters") (keep #(if (> (count %) 6) (str % " has more than 6 characters")) stuff))) ;; Using the same function with map shows the ;; nil results that are filtered by keep. (is (= (list "Clojure has more than 6 characters" nil nil) (map #(if (< 6 (count %)) (str % " has more than 6 characters")) stuff))) (def user {:name "Hubert" :nickname "mrhaki" :age 46}) ;; Returned result from the function is a boolean ;; so it is always included in the result after applying ;; the keep function. (is (= [true true false] (keep #(instance? String (% 1)) user))) ;; Here the function returns a string result or nill. (is (= [":name has a String value" ":nickname has a String value"] (keep (fn [[k v]] (if (instance? String v) (str k " has a String value"))) user)))
Written with Clojure 1.10.1.