collect

This page describes an operation in the collection pipeline pattern. For more context read:

map

Applies given function to each element of input and puts result in output

A simple example:

ruby…
[1,2,3].map {|i| i * i}  
# => [1, 4, 9]
clojure…
(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.