Clojure - Seq Functions

2 minute read

Seq Functions

Clojure’s seq library has functions that work on Clojure’s sequence abstracion.

map

Besides the main use of map it can also be used by taking multiple collections as arguments and taking a collection of functions as an argument.

1(map str ["a" "b" "c"] ["A" "B" "C"])
2; => ("aA" "bB" "cC")

When multiple collections are passed to map the elements of first collections will be passed as the first argument of the mapping function, second collection as second argument and so on.

1(def sum #(reduce + %))
2(def avg #(/ (sum %) (count %)))
3(defn stats
4  [numbers]
5  (map #(% numbers) [sum count avg]))
6
7(stats [3 4 10])
8; => [17 3 17/3]

This example show how map can be used to iterate through list of functions and apply them.

reduce

Two not so obious uses for reduce. First is to use it to transform values of a map, producing a new map with same keys but updated values.

1(reduce (fn [new-map [key val]]
2          (assoc new-map key (inc val)))
3        {}
4        {:max 30 :min 10})
5; => {:max 31 :min 11}

Another is to use reduce to filter keys from a map based on their values.

1(reduce (fn [new-map [key val]]
2          (if (> val 4)
3            (assoc new-map key val)
4            new-map))
5        {}
6        {:a 4.2 :b 5 :c 3})
7; => {:a 4.2 :b 5}

take, drop, take-while, and drop-while

take and drop both take a number and a sequence, returning first n elements or a sequences with first n elements removed

1(take 3 [1 2 3 4 5])
2; => (1 2 3)
3
4(drop 3 [1 2 3 4 5])
5; => (4 5)

take-while and drop-while take a predicate functions - functions that return either true or false, to determine when it should stop taking or dropping.

 1(def mood-calendar
 2  [{:month 1 :mood "happy"}
 3   {:month 2 :mood "sad"}
 4   {:month 3 :mood "depressed"}
 5   {:month 4 :mood "very happy"}])
 6
 7(take-while #(< (:month %) 3) mood-calendar)
 8; => ({:month 1, :mood "happy"}
 9;     {:month 2, :mood "sad"})
10
11(drop-while #(< (:month %) 3) mood-calendar)
12; => ({:month 3, :mood "depressed"}
13;     {:month 4, :mood "very happy"})

filter and some

filter returns all elements of a sequence that test true for a predicate function. It has a similar use case to take-while and drop-while, but filter can end up processing all data which is not always necessary.

some function return the first truthy value returned by a predicate function.

sort and sort-by

sort is used to sort elements in asceding order.

If the sorting is more complicated we can use sort-by sort elements using a function.

1(sort-by count ["aaa" "bb" "c"])
2; => ("c" "bb" "aaa")

concat

concat appends the members of one sequence to the end of another.

1(concat [1 2] [3 4])
2; => (1 2 3 4)