This page describes an operation in the collection pipeline pattern. For more context read:
- Collection Pipeline Article: An article explaining the collection pipeline pattern
- Operation Catalog: The list of selected operations that I have these pages for.
map
Applies given function to each element of input and puts result in output
A simple example:
[1,2,3].map {|i| i * i} # => [1, 4, 9]
(map #(* % %) [1 2 3]) ;; => (1 4 9)
As with any collection operation, if you want to run map on a hash, you need some jiggery-pokery to deal with accessing the keys and values. With destructuring, you can destructure a single pair argument.
clojure…(map (fn [[k,v]] (format "%s (%s)" v k)) {"BR" "Brazil", "DE" "Germany"}) ;; => ("Germany (DE)" "Brazil (BR)")
OO languages need map defined on the Hash class, in which case you need to pass a function with two parameters.
ruby…{BR: 'Brazil', DE: 'Germany'}.map{|k,v| format("%s (%s)", v, k)} # => ["Brazil (BR)", "Germany (DE)"]
If you use a map with a function that may or may not yield a result, you'll get a map that contains a lot of nils. To remove those nils use a filter.
With method chaining, a map function can only operate on a single input collection and thus the supplied function can only take one argument. With a functional style, however, you can have multiple collections which are passed to a multi-argument function. So here in clojure we can use map with any number of collections.
(map + [1 2 3] [10 20 30] [100 200 300]) ; => [111 222 333]
This way of working leads to an idiom to transpose a table. Assume we start with a list of rows:
[[:a1 :b1] [:a2 :b2] [:a3 :b3]]
… and we'd like to turn it into a list of columns
[[:a1 :a2 :a3] [:b1 :b2 :b3]]]
I can do this with:
(apply map vector input)
Of course this is just the transpose operator, but it's a common idiom in lispy languages.