juxt

added
1.1

ns
clojure.core

type
function

(juxt f) (juxt f g) (juxt f g h) (juxt f g h & fs)

Takes a set of functions and returns a fn that is the juxtaposition
of those fns.  The returned fn takes a variable number of args, and
returns a vector containing the result of applying each fn to the
args (left-to-right).
((juxt a b c) x) => [(a x) (b x) (c x)]

                ;; Extract values from a map, treating keywords as functions.
((juxt :a :b) {:a 1 :b 2 :c 3 :d 4})
;;=> [1 2]

            
                ;; "Explode" a value.

((juxt identity name) :keyword)
;;=> [:keyword "keyword"]

(juxt identity name)
...is the same as:
(fn [x] [(identity x) (name x)])

;; eg. to create a map:

(into {} (map (juxt identity name) [:a :b :c :d]))
;;=> {:a "a" :b "b" :c "c" :d "d"}

            
                ;; Get the first character and length of string

((juxt first count) "Clojure Rocks")
;;=> [\\C 13]

            
                ;; sort list of maps by multiple values
(sort-by (juxt :a :b) [{:a 1 :b 3} {:a 1 :b 2} {:a 2 :b 1}])
;;=> [{:a 1 :b 2} {:a 1 :b 3} {:a 2 :b 1}]
            
                ;; Create lookup maps via a specific key

(defn index-by [coll key-fn]
    (into {} (map (juxt key-fn identity) coll)))
;; #'user/index-by

(index-by [{:id 1 :name "foo"} 
           {:id 2 :name "bar"} 
           {:id 3 :name "baz"}] :id)
;;=> {1 {:name "foo", :id 1}, 
;;    2 {:name "bar", :id 2}, 
;;    3 {:name "baz", :id 3}}

(index-by [{:id 1 :name "foo"} 
           {:id 2 :name "bar"} 
           {:id 3 :name "baz"}] :name)
;;=> {"foo" {:name "foo", :id 1}, 
;;    "bar" {:name "bar", :id 2}, 
;;    "baz" {:name "baz", :id 3}}

            
                ((juxt + * min max) 3 4 6)
;;=> [13 72 3 6]
            
                ;; split a sequence into two parts

user=> ((juxt take drop) 3 [1 2 3 4 5 6])
;; => [(1 2 3) (4 5 6)]
            
                ;; Segregate even and odd numbers in collection.

((juxt (partial filter even?) (partial filter odd?)) (range 0 9))
;;=> [(0 2 4 6 8) (1 3 5 7)]
            
                ;;keywords serve as getter functions to produce an ordered vector

((juxt :lname :fname) {:fname "Bill" :lname "Gates"})
=> ["Gates" "Bill"]
            
                ;; sort by two values

(sort-by (juxt :a :b) [{:a 2 :b 4} {:a 1 :b 2} {:a 2 :b 1}])
=> ({:a 1, :b 2} {:a 2, :b 1} {:a 2, :b 4})