In Clojure we can take or drop elements from a collection based on a predicate using the functions take-while
and drop-while
. With the function take-while
we take elements as long as the predicate returns true
. Once the predicate returns false
the function stops returning elements. Using the function drop-while
we skip elements in the collection if the predicate returns true
. If the predicate returns false
the remaining elements in the collection are returned.
In the following example we use take-while
and drop-while
with different collection types:
(ns mrhaki.seq.take-while (:require [clojure.test :refer [is]] [clojure.string :refer [join]])) ;; Simple range of numbers to 10 to invoke ;; take-while and drop-while functions. (def numbers (range 10)) ;; Use take-while to get all number as long as ;; the number is less than 5. (is (= [0 1 2 3 4] (take-while #(< % 5) numbers))) ;; Use drop-while to skip all numbers that are ;; less than 5, so we get all numbers from 5. (is (= [5 6 7 8 9] (drop-while #(< % 5) numbers))) ;; String is a collection of characters so ;; we can use take-while and drop-while. (def s "Clojure Rocks!") (is (= "Clojure " (join (take-while #(not= \R %) s)))) (is (= "Rocks!" (join (drop-while #(not= \R %) s)))) ;; A map structure is a collection of key/value vectors, ;; so take-while and drop-while can be used. (def user {:name "mrhaki" :loves "Clojure" :worksAt "JDriven"}) ;; Helper function to return the length of a keyword. (defn keyword-length "Returns length of keyword." [entry] (.length (name (key entry)))) (is (= {:name "mrhaki"} (into {} (take-while #(= 4 (keyword-length %)) user)))) (is (= {:loves "Clojure" :worksAt "JDriven"} (into {} (drop-while #(= (key %) :name) user))))
Written with Clojure 1.10.1.