Today I learned a neat trick how to transpose a matrix (vector of vectors) in a very concise manner in Clojure.
Assume that you have a data structure like this:
(def input [[1 2 3]
[4 5 6]
[7 8 9]])
And that you need to get a data structure like this:
(def output [[1 4 7]
[2 5 8]
[3 6 9]])
By applying (apply mapv vector input)
you will get the expected result. I discovered the solution on Stack Overflow.
Here’s an explanation, in my own words:
map
function (clojuredocs) can take in more than one collection. mapv
(clojuredocs) behaves in the same way except it outputs a vector.
When several collections are passed, map
will pass ith elements of each collection as arguments to the mapping function. Here’s a nice visualization:
mkarp.core=> (map (partial str) '(1 A) '(2 B) '(3 C))
("123" "ABC")
vector
(clojuredocs) function produces a vector out of its arguments.
So (map vector '(1 A) '(2 B) '(3 C))
will produce a collection of vectors of ith elements from the input collections: all of the 1st elements, all of the 2nd elements and so on:
mkarp.core=> (map vector '(1 A) '(2 B) '(3 C))
([1 2 3] [A B C])