# Elegant solution for inverting zip?

**URL:** <https://www.ruby-forum.com/t/elegant-solution-for-inverting-zip/172089>\
**Category:** Ruby\
**Created:** [July 14, 2009, 3:28pm UTC](https://www.ruby-forum.com/t/elegant-solution-for-inverting-zip/172089 "2009-07-14T15:28:31Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![naething](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e47774/32.png) [@naething](https://www.ruby-forum.com/u/naething)\
**Post date:** [July 14, 2009, 3:28pm UTC](https://www.ruby-forum.com/t/elegant-solution-for-inverting-zip/172089/1 "2009-07-14T15:28:31Z")

</div>

Hi folks,

I came across something I thought should have an obvious answer and  
came up blank. I’m hoping folks could give me a nice solution to this  
problem.

Given the output below:

> > a = [1,2,3,4].zip([5,6,7,8])  
> > =\> [[1, 5], [2, 6], [3, 7], [4, 8]]

I’d like to recover the original two arrays, something like

unzip(a) #=\> [[1,2,3,4],[5,6,7,8]]

The best ordinary solution I could come up with was this:

b = a.each\_with\_object([[],[]]) do |pair, memo|  
memo[0] \<\< pair[0]  
memo[1] \<\< pair[1]  
end

Shorter, but perhaps weirder, is:

require “matrix”  
b = Matrix[\*a].column\_vectors.map(&:to\_a)

Although either of these solutions are likely good enough for my  
needs, neither feel natural to me. Anyone have something better?

-greg

---

<div class="post-metadata">

**Author:** ![naething](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e47774/32.png) [@naething](https://www.ruby-forum.com/u/naething)\
**Post date:** [July 14, 2009, 3:35pm UTC](https://www.ruby-forum.com/t/elegant-solution-for-inverting-zip/172089/2 "2009-07-14T15:35:32Z")

</div>

Hi –

On Tue, 14 Jul 2009, Gregory B. wrote:

> I’d like to recover the original two arrays, something like
> 
> unzip(a) #=\> [[1,2,3,4],[5,6,7,8]]

a.transpose, n’est-ce pas?

David

---

<div class="post-metadata">

**Author:** ![naething](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e47774/32.png) [@naething](https://www.ruby-forum.com/u/naething)\
**Post date:** [July 14, 2009, 3:37pm UTC](https://www.ruby-forum.com/t/elegant-solution-for-inverting-zip/172089/3 "2009-07-14T15:37:17Z")

</div>

On Tue, Jul 14, 2009 at 9:27 AM, Gregory  
Brown[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> require “matrix”  
> b = Matrix[\*a].column\_vectors.map(&:to\_a)

_facepalm_ Array#transpose is what I needed, I can’t believe I forgot  
that. Thanks goes to David Black via IM.

-greg

---

<div class="post-metadata">

**Author:** ![naething](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e47774/32.png) [@naething](https://www.ruby-forum.com/u/naething)\
**Post date:** [July 14, 2009, 4:48pm UTC](https://www.ruby-forum.com/t/elegant-solution-for-inverting-zip/172089/4 "2009-07-14T16:48:54Z")

</div>

Gregory B. wrote:

> On Tue, Jul 14, 2009 at 9:27 AM, Gregory  
> Brown[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > require “matrix”  
> > b = Matrix[\*a].column\_vectors.map(&:to\_a)
> 
> _facepalm_ Array#transpose is what I needed, I can’t believe I forgot  
> that. Thanks goes to David Black via IM.

That’s funny - I was just trying to do more or less the same thing the  
other day. Given an array of [k,v] pairs, I needed to turn it into an  
array of k’s and an array of v’s.

I searched for a built-in method to do this, couldn’t find it, so went  
for the obvious solution:

```
ks = src.collect { |k,v| k }
vs = src.collect { |k,v| v }

```

But now I know a better way:

```
ks, vs = src.transpose

```

Thanks for sharing!
