ClojureDocs

Nav

Namespaces

map

clojure.core

Available since 1.0 (source)
  • (map f)
  • (map f coll)
  • (map f c1 c2)
  • (map f c1 c2 c3)
  • (map f c1 c2 c3 & colls)
Returns a lazy sequence consisting of the result of applying f to
the set of first items of each coll, followed by applying f to the
set of second items in each coll, until any one of the colls is
exhausted.  Any remaining items in other colls are ignored. Function
f should accept number-of-colls arguments. Returns a transducer when
no collection is provided.
18 Examples
(map inc [1 2 3 4 5])
;;=> (2 3 4 5 6)


;; map can be used with multiple collections. Collections will be consumed
;; and passed to the mapping function in parallel:
(map + [1 2 3] [4 5 6])
;;=> (5 7 9)


;; When map is passed more than one collection, the mapping function will
;; be applied until one of the collections runs out:
(map + [1 2 3] (iterate inc 1))
;;=> (2 4 6)



;; map is often used in conjunction with the # reader macro:
(map #(str "Hello " % "!" ) ["Ford" "Arthur" "Tricia"])
;;=> ("Hello Ford!" "Hello Arthur!" "Hello Tricia!")

;; A useful idiom to pull "columns" out of a collection of collections. 
;; Note, it is equivalent to:
;; user=> (map vector [:a :b :c] [:d :e :f] [:g :h :i])

(apply map vector [[:a :b :c]
                   [:d :e :f]
                   [:g :h :i]])

;;=> ([:a :d :g] [:b :e :h] [:c :f :i])

;; From http://clojure-examples.appspot.com/clojure.core/map
;; map sends key-value pairs from a hash-map
(map #(vector (first %) (* 2 (second %)))
            {:a 1 :b 2 :c 3})
;;=> ([:a 2] [:b 4] [:c 6])

;; or the same thing using destructuring
(map (fn [[key value]] [key (* 2 value)])
            {:a 1 :b 2 :c 3})
;;=> ([:a 2] [:b 4] [:c 6])

(into {} *1)
;;=> {:a 2, :b 4, :c 6}
;; Use a hash-map as a function to translate values in a collection from the 
;; given key to the associated value

user=> (map {2 "two" 3 "three"} [5 3 2])
(nil "three" "two")

;; then use (filter identity... to remove the nils
user=> (filter identity (map {2 "two" 3 "three"} [5 3 2]))
("three" "two")

;; an alternative to the above map+filter steps is keep.
(keep {2 "two" 3 "three"} [5 3 2])
;;=> ("three" "two")
;; mapping over a hash-map applies (into) first. 
;; need to use functions that deal with arrays (fn [[key val]] ...)
(map pprint {:key :val :key1 :val1})
([:key :val]
[:key1 :val1]
nil nil)

;;above, the pprint output appears to be part of the return value but it's not:
(hash-set (map pprint {:key :val :key1 :val1}))
[:key :val]
[:key1 :val1]
#{(nil nil)}

(map second {:key :val :key1 :val1})
;;=>(:val :val1)

(map last {:x 1 :y 2 :z 3})
;;=> (1 2 3)
(map fn [a 4 x]
        [b 5 y]
        [c 6])    
;        ^ ^
; applies fn to a b c as (fn a b c)
; applies fn to 4 5 6 as (fn 4 5 6)
; ignores (x y)
; returns a list of results
; equivalent to (list (fn a b c) (fn 4 5 6))

;example
(map list [1 2 3]
         '(a b c)
         '(4 5))

user=> (map list  [1 2 3] '(a b c) '(4 5))
((1 a 4) (2 b 5))
;same as
user=> (list (list 1 'a 4) (list 2 'b 5))
((1 a 4) (2 b 5))
; map passed two collection arguments. From 4Clojure Problem #157

(def d1 [:a :b :c])
(#(map list % (range)) d1)
;;=> ((:a 0) (:b 1) (:c 2))
;; Used without a collection, map will create a transducer:
(def xf (map inc))

;; We can now apply this transducer to a sequence:
(transduce xf conj (range 5))
;; => [1 2 3 4 5]
;; Extract keyword from a collection of obj
(map :a '({:a 1 :b 0} {:a 2 :b 0} {:a 3 :b 1} {:a 3 :b 0}))
;; =>(1 2 3 3)
;;get the keys from a map with entries of certain values
(let [m {:x 1 :y 2 :z 3}
      vset #{2 3}]
  (map first (filter (comp vset last) m)))
;;=> (:y :z)

(filter (comp #{2 3} last) {:x 1 :y 2 :z 3})
;;=> ([:y 2] [:z 3])

;; deeper destructuring
(def ds [ {:a 1 :b 2 :c [:foo :bar]}
          {:a 9 :b 8 :c [:baz :zoo]}
          {:a 1 :b 2 :c [:dog :cat]} ])

(->> ds 
    (map (fn [{a :a, b :b, [lhs rhs] :c}] 
            [(str "a:" a " c2:" rhs)])))
;;=> (["a:1 c2::bar"] ["a:9 c2::zoo"] ["a:1 c2::cat"])
;;map taking a collection of functions as an argument

(def sum #(reduce + %))

(def average #(/ (sum %) (count %)))

;;apply a function to a collection
(defn results [coll]
  (map #(% coll) [sum average count]))

(results [10 20 30 40 50])
;;[150 30 5]
(def my-coll [
              {:m 1, :val 12}
              {:m 2, :val 3}
              {:m 3, :val 32}])

(map #(:val %) my-coll)
;;(12 3 32)

;;get total:
(reduce + (map #(:val %) my-coll))
;;47
;;map practical example

(def months ["jan" "feb" "mar"])

(def temps [5 7 12])

(defn unify
  [month temp]
  {:month month
   :temp temp})

(map unify months temps)

;;({:month "jan", :temp 5}
;; {:month "feb", :temp 7}
;; {:month "mar", :temp 12})
;;map Function collection1 collection2

(map vector '(1 2 3 4) [:a :b :c :d])

;;([1 :a] [2 :b] [3 :c] [4 :d])
 ;multiplication of rows and columns
(def matrix
  [
   [1  2 3  4   5];=>120
   [1  2 3  4   5];=>120
   [1  2 3  4   5];=>120
   [1  2 3  4   5]]);120  
  ;(1 16 81 256 625)

;;columns multiplication
(apply map * matrix)
;;(1 16 81 256 625)

;;rows multiplication
(map #(reduce * %) matrix)
;;(120 120 120 120)
;; Notice how the args of each collection are processed in parallel by the
;; function provided to `map` -- in this case, an #(anonymous function) 
;;that takes %1 = the first coll elements and %2 the second coll elements.
;; map will process the collections in parallel and will terminate when it reaches 
;; the end of the shortest collection.  In this case, they are equal length.

 (map #(str "Hello " %1 %2)  ["Tennessee " "James " "John "]  ["Ernie Ford" "Bond" "Smith"])

output> ("Hello Tennessee Ernie Ford" "Hello James Bond" "Hello John Smith")
;; running several functions on the same argument

(map #(% 0) (list inc dec zero?))
;=> (1 -1 true)

(map #(% 0) [inc dec zero?])
;=> (1 -1 true)

;; but not

(map #(% 0) `(inc dec zero?))
;=> (nil nil nil)

(map #(% 0) '(inc dec zero?))
;=> (nil nil nil)

;; https://stackoverflow.com/questions/69925317/why-map-fn-f-f-0-inc-returns-nil-in-clojure
;; Be careful with `map`, closures, and anonymous functions

(defn typical-closure []
  (let [names (atom [])]
    (fn [arg] (swap! names conj arg) @names)))

;; This works as expected: one function gets created and mapped

(defmacro list-maker [fun args & body]
  `(defn ~fun ~args
     (map (typical-closure) '~body)))

(list-maker foo [x] 1 2 3 4 5)
(foo 100) ; ([1] [1 2] [1 2 3] [1 2 3 4] [1 2 3 4 5])

;; This version recomputes the function for each mappand!

(defmacro list-maker-oops [fun args & body]
  `(defn ~fun ~args
     (map #((typical-closure) %) '~body)))

;; facepalm
(list-maker-oops foo [x] 1 2 3 4 5)
(foo 100) ; ([1] [2] [3] [4] [5])
See Also

Returns a lazy sequence consisting of the result of applying f to 0 and the first item of coll, fo...

Added by mmwaikar

Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead ...

Added by gstamp

Maps an expression across an array a, using an index named idx, and return value named ret, initia...

Added by gstamp

Returns the result of applying concat to the result of applying map to f and colls. Thus function...

Added by adereth

Returns a lazy sequence of the non-nil results of (f item). Note, this means false return values w...

Added by ryo

Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn...

Returns a vector consisting of the result of applying f to the set of first items of each coll, fo...

Added by phreed

f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to...

Added by phreed

Runs the supplied procedure (via reduce), for purposes of side effects, on successive items in the...

Added by jafingerhut

Returns a lazy sequence of the items in coll for which (pred item) returns logical true. pred must...

Added by zackteo
1 Note
    By , created 12.1 years ago

    To create a hashmap, use the hash-map function, or the {...} sugar:

    (= {:a 1 :b 2 :c 3} (hash-map :a 1 :b 2 :c 3))