Returns the result of applying concat to the result of applying map
to f and colls. Thus function f should return a collection.
user=> (mapcat (fn [[k v]]
(for [[k2 v2] v]
(concat [k k2] v2)))
'{:a {:x (1 2) :y (3 4)}
:b {:x (1 2) :z (5 6)}})
((:a :x 1 2) (:a :y 3 4) (:b :x 1 2) (:b :z 5 6))
user=> (require '[clojure.string :as cs])
nil
;; Suppose you have a fn in a `map` that itself returns
;; multiple values.
user=> (map #(cs/split % #"\d") ["aa1bb" "cc2dd" "ee3ff"])
(["aa" "bb"] ["cc" "dd"] ["ee" "ff"])
;; Now, if you want to concat them all together, you *could*
;; do this:
user=> (apply concat (map #(cs/split % #"\d") ["aa1bb" "cc2dd" "ee3ff"]))
("aa" "bb" "cc" "dd" "ee" "ff")
;; But `mapcat` can save you a step:
user=> (mapcat #(cs/split % #"\d") ["aa1bb" "cc2dd" "ee3ff"])
("aa" "bb" "cc" "dd" "ee" "ff")
;; Suppose you've got a function that takes a value ;; and returns a list of things from it, for example: (defn f1 [n] [(- n 1) n (+ n 1)]) (f1 1) ;=> [0 1 2] ;; Perhaps you'd like to map it onto each item in a collection: (map f1 [1 2 3]) ;=> ([0 1 2] [1 2 3] [2 3 4]) ;; But suppose you wanted them all concatenated? You could do this: (apply concat (map f1 [1 2 3])) ;=> (0 1 2 1 2 3 2 3 4) ;; Or you could get the same thing with `mapcat`: (mapcat f1 [1 2 3]) ;=> (0 1 2 1 2 3 2 3 4)
; Flatten a map, consing keys on to each nested vector
(mapcat (fn [[k vs]] (map (partial cons k) vs)) {:foo [[1 2] [3 2]] :bar [[3 1]]})
;=> ((:foo 1 2) (:foo 3 2) (:bar 3 1))
(defn mapcat
"Returns the result of applying concat to the result of applying map
to f and colls. Thus function f should return a collection."
{:added "1.0"}
[f & colls]
(apply concat (apply map f colls)))
Comments top
No comments for mapcat. Log in to add a comment.