How to combine two vectors of vectors by elements in clojure?

Suppose I have:

'[[ccc] [yyy] [mmm]] 

and

 '[[rgb] [rgb] [rgb]] 

and I would like to:

 '[[[c,r] [c,g] [c,b]] [[y,r] [y,g] [y,b]] [[m,r] [m,g] [m,b]]] 

What is an elegant way to do this in clojure?

+8
list vector clojure
source share
4 answers
 (def a '[[ccc] [yyy] [mmm]]) (def b '[[rgb] [rgb] [rgb]]) (mapv (partial mapv vector) ab) ;; will work with arbitrary number ;; of equal sized arguments ;=> [[[cr] [cg] [cb]] [[yr] [yg] [yb]] [[mr] [mg] [mb]]] 
+7
source share

Consider using core.matrix for such things.

It will manipulate nested vectors quite efficiently as matrices, but it also has much more powerful material if you need it (for example, support for accelerated libraries of native matrices via JBLAS). It is formed as the final library / API for calculating matrices in Clojure.

In this case, you can simply use "emap" to apply the functional element to the two matrices:

 (use 'core.matrix) (def cym '[[ccc] [yyy] [mmm]]) (def rgb '[[rgb] [rgb] [rgb]]) (emap vector cym rgb) => [[[cr] [cg] [cb]] [[yr] [yg] [yb]] [[mr] [mg] [mb]]] 
+4
source share

partition and interleave will get you there as seqs:

 (def a '[[ccc] [yyy] [mmm]]) (def b '[[rgb] [rgb] [rgb]]) (map (partial partition 2) (map interleave ab)) ;=> (((cr) (cg) (cb)) ; ((yr) (yg) (yb)) ; ((mr) (mg) (mb))) 

If for some reason you need to convert the answer into nested vectors, it might be worth considering this question .

+3
source share

Here's another implementation:

 (defn combine-vectors [& vecs] (apply map (partial map vector) vecs)) 

Replace map with mapv to get vectors instead of lazy seqs from this.

+2
source share

All Articles