# Array#zip

**URL:** <https://www.ruby-forum.com/t/array-zip/108963>\
**Category:** Rails\
**Created:** [July 10, 2007, 1:47am UTC](https://www.ruby-forum.com/t/array-zip/108963 "2007-07-10T01:47:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![kapslok](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/46a35a/32.png) [@kapslok](https://www.ruby-forum.com/u/kapslok)\
**Post date:** [July 10, 2007, 1:47am UTC](https://www.ruby-forum.com/t/array-zip/108963/1 "2007-07-10T01:47:35Z")

</div>

I’m having a problem trying to wrap the zip method in a function.

If I put the following into irb:

[1,2,3].zip [4,5,6],[7,8,9],[10,11,12],[13,14,15]

I get:

=\> [[1, 4, 7, 10, 13], [2, 5, 8, 11, 14], [3, 6, 9, 12, 15]]

Now I’m trying to wrap this into a function, where I can pass in an  
array of arrays as a parameter to get the same output. I have tried the  
following:

def transpose(matrix)  
matrix[0].zip matrix[1…-1]  
end

However when I pass the following into the function, I get a totally  
different result:

transpose([1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15])  
=\> [[1, [4, 5, 6]], [2, [7, 8, 9]], [3, [10, 11, 12]]]

If I assign the array of arrays to a variable:

m = [1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15]

And then perform the operation manually, I get the correct result:

m[0].zip m[1],m[2],m[3],m[4]  
=\> [[1, 4, 7, 10, 13], [2, 5, 8, 11, 14], [3, 6, 9, 12, 15]]

I’ve been mucking around for half a day now, trying the get this damn  
thing to output correctly, but I’m not sure what I’m doing wrong.

I would like the output as above. Even better still would be the result  
repacked as per the original parameter:

=\> [[1,4,7],[10,13,2],[5,8,11],[14,3,6],[9,12,15]]

Can anybody help me?

---

<div class="post-metadata">

**Author:** ![kapslok](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/46a35a/32.png) [@kapslok](https://www.ruby-forum.com/u/kapslok)\
**Post date:** [July 10, 2007, 4:31am UTC](https://www.ruby-forum.com/t/array-zip/108963/2 "2007-07-10T04:31:22Z")

</div>

Hi –

On Tue, 10 Jul 2007, Kaps L. wrote:

> =\> [[1, 4, 7, 10, 13], [2, 5, 8, 11, 14], [3, 6, 9, 12, 15]]
> 
> I’ve been mucking around for half a day now, trying the get this damn  
> thing to output correctly, but I’m not sure what I’m doing wrong.
> 
> I would like the output as above. Even better still would be the result  
> repacked as per the original parameter:
> 
> =\> [[1,4,7],[10,13,2],[5,8,11],[14,3,6],[9,12,15]]
> 
> Can anybody help me?

It’s probably a better question for the ruby-talk list (general Ruby  
questions), but yes, I can help.

Arrays already have a transpose method:

```
irb(main):014:0> m
=> [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]]
irb(main):015:0> m.transpose
=> [[1, 4, 7, 10, 13], [2, 5, 8, 11, 14], [3, 6, 9, 12, 15]]

```

If for some reason you need to roll your own, you’d need to do:

matrix[0].zip(\*matrix[1…-1]) # note the \* operator

Without the \* you’re doing this:

[1,2,3].zip([[4,5,6], [7,8,9], [10,11,12], [13,14,15]])

i.e., you’re mapping 1,2,3 to an array with four elements. You really  
want to map it to four arrays; the \* operator takes care of  
“un-arraying” the big array into a list of smaller arrays.

David

–

- Books:  
RAILS ROUTING (new! [http://www.awprofessional.com/title/0321509242](http://www.awprofessional.com/title/0321509242))  
RUBY FOR RAILS ([Ruby for Rails](http://www.manning.com/black))
- Ruby/Rails training  
& consulting: Ruby Power and Light, LLC ([http://www.rubypal.com](http://www.rubypal.com))

---

<div class="post-metadata">

**Author:** ![kapslok](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/46a35a/32.png) [@kapslok](https://www.ruby-forum.com/u/kapslok)\
**Post date:** [July 10, 2007, 5:10am UTC](https://www.ruby-forum.com/t/array-zip/108963/3 "2007-07-10T05:10:27Z")

</div>

Hi –

On Tue, 10 Jul 2007, Kaps L. wrote:

> > David  
> > array of arrays that have 3 elements, instead of five?
> 
> =\> [[1,4,7],[10,13,2],[5,8,11],[14,3,6],[9,12,15]]

In ActiveSupport there’s a method called Array#in\_groups\_of, so you  
could do:

m.transpose.flatten.in\_groups\_of(3)

Flattening will flatten everything, so if you’ve got more complex  
array nesting, beware (or use the flattenx extension, or wait for Ruby  
1.9/2.0).

> Thanks again.
> 
> P.S. Your routing book looks cool, is there a sample chapter available?

Yes; if you go to [http://www.awprofessional.com/title/0321509242](http://www.awprofessional.com/title/0321509242)  
there’s a “Excerpts” link under the “More Information” header.

David

–

- Books:  
RAILS ROUTING (new! [http://www.awprofessional.com/title/0321509242](http://www.awprofessional.com/title/0321509242))  
RUBY FOR RAILS ([Ruby for Rails](http://www.manning.com/black))
- Ruby/Rails training  
& consulting: Ruby Power and Light, LLC ([http://www.rubypal.com](http://www.rubypal.com))

---

<div class="post-metadata">

**Author:** ![kapslok](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/46a35a/32.png) [@kapslok](https://www.ruby-forum.com/u/kapslok)\
**Post date:** [July 10, 2007, 4:45am UTC](https://www.ruby-forum.com/t/array-zip/108963/4 "2007-07-10T04:45:05Z")

</div>

unknown wrote:

> Hi –  
> Arrays already have a transpose method:
> 
> ```
> irb(main):014:0> m
> => [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]]
> irb(main):015:0> m.transpose
> => [[1, 4, 7, 10, 13], [2, 5, 8, 11, 14], [3, 6, 9, 12, 15]]
> 
> ```
> 
> David

Thanks so much David. I tried the transpose method but a different  
result, which is why I looked at rolling my own. Now that I’ve tried it  
again it works. I must have passed the array in differently. Now that I  
try it works fine.

I was wondering why I hadn’t got a reply yet, so next time I’ll post to  
the Ruby forum.

While I’ve got you, is there an easy way to repack the result into an  
array of arrays that have 3 elements, instead of five?

=\> [[1,4,7],[10,13,2],[5,8,11],[14,3,6],[9,12,15]]

Thanks again.

P.S. Your routing book looks cool, is there a sample chapter available?

---

<div class="post-metadata">

**Author:** ![kapslok](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/46a35a/32.png) [@kapslok](https://www.ruby-forum.com/u/kapslok)\
**Post date:** [July 10, 2007, 6:12am UTC](https://www.ruby-forum.com/t/array-zip/108963/5 "2007-07-10T06:12:46Z")

</div>

unknown wrote:

> In ActiveSupport there’s a method called Array#in\_groups\_of, so you  
> could do:
> 
> m.transpose.flatten.in\_groups\_of(3)

Thanks, that did the trick. That method is really really handy. It’s  
just cut down the work I’ve got to do 300%.

I really appreciate you taking the time out to help me out. Thank you.
