A higher order function that takes one or more functions as arguments, and returns a function.
When calling the returned function with zero or more arguments, the arguments are passed to each of the functions originally passed to juxt, and the returned result is a vector containing each result from these functions.
We’ll start with a toy example to show the basic functionality. We want to return the result of various math functions applied to two numbers.
(defn do-math [a b]
[(+ a b)
(- a b)
(* a b)
(/ a b)
(mod a b)
(max a b)
(min a b)])
(do-math 6 3)
=> [9 3 18 2 0 6 3]
We can replace this with juxt for a more concise version.
(def do-math (juxt + - * / mod max min))
(do-math 6 3)
=> [9 3 18 2 0 6 3]
More practically, juxt can be used to extract certain values from a collection of hash-maps, in this case a persons id and name.
(->>
[{:id 1 :name "John" :age 5}
{:id 2 :name "Gale" :age 5}
{:id 3 :name "Zoe" :age 7}
{:id 4 :name "Diana" :age 7}
{:id 5 :name "Aden" :age 5}
{:id 6 :name "Alex" :age 7}]
(map (juxt :id :name)))
=>
([1 "John"]
[2 "Gale"]
[3 "Zoe"]
[4 "Diana"]
[5 "Aden"]
[6 "Alex"])
We can expand on this idea and create a lookup using the into function.
(def people
(->> [{:id 1 :name "John" :age 5}
{:id 2 :name "Gale" :age 5}
{:id 3 :name "Zoe" :age 7}
{:id 4 :name "Diana" :age 7}
{:id 5 :name "Aden" :age 5}
{:id 6 :name "Alex" :age 7}]
(map (juxt :id :name))
(into {})))
(get people 1)
=> "John"
(def people
(->> [{:id 1 :name "John" :age 5}
{:id 2 :name "Gale" :age 5}
{:id 3 :name "Zoe" :age 7}
{:id 4 :name "Diana" :age 7}
{:id 5 :name "Aden" :age 5}
{:id 6 :name "Alex" :age 7}]
(map (juxt :id identity))
(into {})))
(get people 3)
=> {:id 3 :name "Zoe" :age 7}
Juxt can be handy if you want to sort by more than one field, in this case we sort by age first and then by name.
(def people
(->> [{:id 1 :name "John" :age 5}
{:id 2 :name "Gale" :age 5}
{:id 3 :name "Zoe" :age 7}
{:id 4 :name "Diana" :age 7}
{:id 5 :name "Aden" :age 5}
{:id 6 :name "Alex" :age 7}]
(sort-by (juxt :age :name))))
=>
({:id 5 :name "Aden" :age 5}
{:id 2 :name "Gale" :age 5}
{:id 1 :name "John" :age 5}
{:id 6 :name "Alex" :age 7}
{:id 4 :name "Diana" :age 7}
{:id 3 :name "Zoe" :age 7})