(apply f args) (apply f x args) (apply f x y args) (apply f x y z args) (apply f a b c d & args)
Applies fn f to the argument list formed by prepending intervening arguments to args.
(def *strings* ["str1" "str2" "str3"])
;; #'user/*strings*
;; Oops!
(str *strings*)
;;=> "[\\"str1\\" \\"str2\\" \\"str3\\"]"
;; Yay!
(apply str *strings*)
;;=> "str1str2str3"
;; Note the equivalence of the following two forms
(apply str ["str1" "str2" "str3"]) ;;=> "str1str2str3"
(str "str1" "str2" "str3") ;;=> "str1str2str3"
;; If you were to try
(max [1 2 3])
;;=> [1 2 3]
;; You would get '[1 2 3]' for the result. In this case, 'max' has received one
;; vector argument, and the largest of its arguments is that single vector.
;; If you would like to find the largest item **within** the vector, you would need
;; to use `apply`
(apply max [1 2 3])
;;=> 3
;; which is the same as
(max 1 2 3)
;;=> 3
;; Here's an example that uses the optional second argument, args:
(apply map vector [[:a :b] [:c :d]])
;;=> ([:a :c] [:b :d])
;; In this example, 'f' = 'map', 'args' = 'vector', and argseq = '[:a :b] [:c :d]',
;; making the above code equivalent to
(map vector [:a :b] [:c :d])
;;=> ([:a :c] [:b :d]) ;Same answer as above
;; It might help to think of 'map' and 'vector' as "slipping inside" the argument
;; list ( '[[:a :b] [:c :d]]' ) to give '[map vector [:a :b] [:c :d]]' , which
;; then becomes the executable form '(map vector [:a :b] [:c :d])' .
;; only functions can be used with apply. 'and' is a macro
;; because it needs to evaluate its arguments lazily and so
;; does not work with apply.
(apply and (list true true false true)
;; RuntimeException : cannot take value of a macro
;; This can be circumvented with another macro.
;; But understand what is happening
;; http://stackoverflow.com/questions/5531986/treat-clojure-macro-as-a-function
(defmacro make-fn [m]
`(fn [& args#]
(eval
(cons '~m args#))))
(apply (make-fn and) '(true true false true))
;;=> false
;; 'apply' is used to apply an operator to its operands.
(apply + '(1 2)) ; equivalent to (+ 1 2)
;;=> 3
;; You can also put operands before the list of
;; operands and they'll be consumed in the list of operands
(apply + 1 2 '(3 4)) ; equivalent to (apply + '(1 2 3 4))
;;=> 10
;; You can use map and apply together to drill one level deep in a collection
;; of collections, in this case returning a collection of the max of each
;; nested collection
(map #(apply max %) [[1 2 3][4 5 6][7 8 9]])
;;=> (3 6 9)
;; Using `apply` with optional keyword parameters:
(defn add2 [a & {:keys [plus] :or {plus 0}}]
(+ 2 plus a))
(add2 4) ; => 6
(add2 4 :plus 1) ; => 7
(apply add2 [4]) ; => 6
(apply add2 [4 {:plus 1}]) ; => IllegalArgumentException
(apply add2 [4 :plus 1]) ; => 7
;; Transpose a matrix
(def A [[1 2]
[3 4]])
(apply map vector A) ; ([1 3] [2 4])
;; Use apply to map a function over a collection of pairs of arguments
(map (partial apply +) [[1 2] [3 4]]) ; => (3 7)
;; this is equivalent to '((+ 1 2) (+ 3 4))
; Remove elements from a set with disj
(disj #{1 2 3} 2 3)
=> #{1}
; Relative complement of two sets (difference)
(apply disj #{2 3 4} #{1 2 3})
=> #{4}
; the above is same as calling
(disj #{2 3 4} 1 2 3)