# Array and hash combine methods

**URL:** https://rubytalk.org/t/array-and-hash-combine-methods/33724
**Category:** ruby-talk
**Created:** [14 December 2006 01:22 UTC](https://rubytalk.org/t/array-and-hash-combine-methods/33724 "2006-12-14T01:22:44Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![glen](https://avatars.discourse-cdn.com/v4/letter/g/8c91f0/32.png) [@glen](https://rubytalk.org/u/glen)
#### Post date: [14 December 2006 01:22 UTC](https://rubytalk.org/t/array-and-hash-combine-methods/33724/1 "2006-12-14T01:22:44Z")

</div>

Just thought I'd post a solution I came up with to finding  
combinations (as in, permutations and combinations) of arrays. For  
example, combining:

[1,2] and [3,4,5]

should return:

[[1,3],[1,4],[1,5],[2,3],[2,4],[2,5]]

which is easy enough. But I wanted something that combine several  
arrays at once, ie:

[[1,2],[3,4,5],[6,7]].combine  
=\> [[1, 3, 6], [1, 3, 7], [1, 4, 6], [1, 4, 7], [1, 5, 6], [1, 5, 7],  
[2, 3, 6], [2, 3, 7], [2, 4, 6], [2, 4, 7], [2, 5, 6], [2, 5, 7]]

I had a look around and couldn't find anything that worked for more  
than two arrays, so I wrote my own:

class Array  
&nbsp;&nbsp;#expects self to be an array of arrays, returns all the combinations possible  
&nbsp;&nbsp;def combine  
&nbsp;&nbsp;&nbsp;&nbsp;#checks  
&nbsp;&nbsp;&nbsp;&nbsp;output\_length = 1  
&nbsp;&nbsp;&nbsp;&nbsp;periods = []  
&nbsp;&nbsp;&nbsp;&nbsp;reverse.each { |sub\_arr|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;periods \<\< output\_length  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "combine needs an array of arrays!" if !sub\_arr.is\_a? Array  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "combine is meaningless unless all the sub\_arrays have at  
least one element!" if sub\_arr.length == 0  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;output\_length \*= sub\_arr.length  
&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;periods.reverse!  
&nbsp;&nbsp;&nbsp;&nbsp;output = (1..output\_length).map { Array.new(length) }  
&nbsp;&nbsp;&nbsp;&nbsp;output.each\_index { |i|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;periods.each\_index { |j|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;output[i][j] = self[j][(i/periods[j])%self[j].length]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;output  
&nbsp;&nbsp;end  
end

And the corresponding hash method:

class Hash  
&nbsp;&nbsp;#expects a hash eg. {a=\>[1,2], b=\>[3,4]}  
&nbsp;&nbsp;#returns an array eg. [{a=\>1,b=\>3}, {a=\>1,b=4}, {a=\>2,b=\>3}, {a=\>2,b=4}]  
&nbsp;&nbsp;def combine  
&nbsp;&nbsp;&nbsp;&nbsp;values.combine.map { |comb|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hash[\*keys.zip(comb).inject([]) { |arr,e| arr + e }]  
&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;end  
end

I'd love to hear other solutions to this problem - and where I should  
have looked to find them... Oh and if anyone has suggestions for a  
better name than 'combine', that'd be great.

Cheers,  
-glen.

---

<div class="post-metadata">

### Author: ![Olivier](https://avatars.discourse-cdn.com/v4/letter/o/d2c977/32.png) [@Olivier](https://rubytalk.org/u/Olivier)
#### Post date: [14 December 2006 10:44 UTC](https://rubytalk.org/t/array-and-hash-combine-methods/33724/2 "2006-12-14T10:44:37Z")

</div>

There is a Enumerable.combinations method in ruby facets which works like  
this. Take a look at :

[http://facets.rubyforge.org/api/core/classes/Enumerable.html#M000555](http://facets.rubyforge.org/api/core/classes/Enumerable.html#M000555)

> **···**
>
> Le jeudi 14 décembre 2006 02:22, glen a écrit :
> 
> > Just thought I'd post a solution I came up with to finding  
> > combinations (as in, permutations and combinations) of arrays. For  
> > example, combining:
> > 
> > [1,2] and [3,4,5]
> > 
> > should return:
> > 
> > [[1,3],[1,4],[1,5],[2,3],[2,4],[2,5]]
> > 
> > which is easy enough. But I wanted something that combine several  
> > arrays at once, ie:
> > 
> > [[1,2],[3,4,5],[6,7]].combine  
> > =\> [[1, 3, 6], [1, 3, 7], [1, 4, 6], [1, 4, 7], [1, 5, 6], [1, 5, 7],  
> > [2, 3, 6], [2, 3, 7], [2, 4, 6], [2, 4, 7], [2, 5, 6], [2, 5, 7]]
> 
> --  
> Olivier

---

<div class="post-metadata">

### Author: ![Juan\_Matias](https://avatars.discourse-cdn.com/v4/letter/j/c6cbf5/32.png) [@Juan\_Matias](https://rubytalk.org/u/Juan_Matias)
#### Post date: [8 June 2010 03:52 UTC](https://rubytalk.org/t/array-and-hash-combine-methods/33724/3 "2010-06-08T03:52:17Z")

</div>

glen wrote:

> Just thought I'd post a solution I came up with to finding  
> combinations (as in, permutations and combinations) of arrays. For  
> example, combining:
> 
> [1,2] and [3,4,5]
> 
> should return:
> 
> [[1,3],[1,4],[1,5],[2,3],[2,4],[2,5]]
> 
> which is easy enough. But I wanted something that combine several  
> arrays at once, ie:
> 
> [[1,2],[3,4,5],[6,7]].combine  
> =\> [[1, 3, 6], [1, 3, 7], [1, 4, 6], [1, 4, 7], [1, 5, 6], [1, 5, 7],  
> [2, 3, 6], [2, 3, 7], [2, 4, 6], [2, 4, 7], [2, 5, 6], [2, 5, 7]]

And why not something like:

&nbsp;&nbsp;[1,2].combine([3,4]).combine([5,6,7])

I do that with this code:

class Array  
&nbsp;&nbsp;def combine(otherArray)  
&nbsp;&nbsp;&nbsp;&nbsp;aux =   
&nbsp;&nbsp;&nbsp;&nbsp;self.each do |self\_elem|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;otherArray.each do |other\_elem|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aux \<\< [self\_elem,other\_elem]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;aux.map {|elem| elem.flatten }  
&nbsp;&nbsp;end  
end

Juan Matias

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

### Author: ![Gavin\_Kistner3](https://avatars.discourse-cdn.com/v4/letter/g/dfb087/32.png) [@Gavin\_Kistner3](https://rubytalk.org/u/Gavin_Kistner3)
#### Post date: [8 June 2010 04:15 UTC](https://rubytalk.org/t/array-and-hash-combine-methods/33724/4 "2010-06-08T04:15:11Z")

</div>

Juan, it would appear that glen posted this question/tip 3.5 years  
ago. Any reason you were responding to it now? (Which, in turn, lured  
me into responding. 🙂

> **···**
>
> On Jun 7, 9:52 pm, Juan Matias \<jmrepe...@gmail.com\> wrote:
> 
> > glen wrote:  
> > \> Just thought I'd post a solution I came up with to finding  
> > \> combinations (as in, permutations and combinations) of arrays. For  
> > \> example, combining:

---

<div class="post-metadata">

### Author: ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)
#### Post date: [8 June 2010 07:36 UTC](https://rubytalk.org/t/array-and-hash-combine-methods/33724/5 "2010-06-08T07:36:08Z")

</div>

I'd rather do this:

module Enumerable  
&nbsp;&nbsp;def combine(enum)  
&nbsp;&nbsp;&nbsp;&nbsp;if block\_given?  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;each do |\*a|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enum.each do |\*b|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield \*a, \*b  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self  
&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enum\_for(:combine, enum)  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end  
end

[1,2].combine([3,4]) do |\*a|  
&nbsp;&nbsp;p a  
end

puts "--------------"

[1,2].combine([3,4]).each do |\*a|  
&nbsp;&nbsp;p a  
end

puts "--------------"

[1,2].combine([3,4]).combine([5,6]) do |\*a|  
&nbsp;&nbsp;p a  
end

puts "--------------"

[1,2].combine([3,4]).combine([5,6]).each do |\*a|  
&nbsp;&nbsp;p a  
end

Kind regards

robert

> **···**
>
> 2010/6/8 Juan Matias \<jmrepetti@gmail.com\>:
> 
> > glen wrote:
> > 
> > > Just thought I'd post a solution I came up with to finding  
> > > combinations (as in, permutations and combinations) of arrays. For  
> > > example, combining:
> > > 
> > > [1,2] and [3,4,5]
> > > 
> > > should return:
> > > 
> > > [[1,3],[1,4],[1,5],[2,3],[2,4],[2,5]]
> > > 
> > > which is easy enough. But I wanted something that combine several  
> > > arrays at once, ie:
> > > 
> > > [[1,2],[3,4,5],[6,7]].combine  
> > > =\> [[1, 3, 6], [1, 3, 7], [1, 4, 6], [1, 4, 7], [1, 5, 6], [1, 5, 7],  
> > > [2, 3, 6], [2, 3, 7], [2, 4, 6], [2, 4, 7], [2, 5, 6], [2, 5, 7]]
> > 
> > And why not something like:
> > 
> > [1,2].combine([3,4]).combine([5,6,7])
> > 
> > I do that with this code:
> > 
> > class Array  
> > def combine(otherArray)  
> > aux =   
> > self.each do |self\_elem|  
> > otherArray.each do |other\_elem|  
> > aux \<\< [self\_elem,other\_elem]  
> > end  
> > end  
> > aux.map {|elem| elem.flatten }  
> > end  
> > end
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)

---

<div class="post-metadata">

### Author: ![Juan\_Matias](https://avatars.discourse-cdn.com/v4/letter/j/c6cbf5/32.png) [@Juan\_Matias](https://rubytalk.org/u/Juan_Matias)
#### Post date: [8 June 2010 04:33 UTC](https://rubytalk.org/t/array-and-hash-combine-methods/33724/6 "2010-06-08T04:33:24Z")

</div>

Gavin Kistner wrote:

> **···**
>
> > On Jun 7, 9:52�pm, Juan Matias \<jmrepe...@gmail.com\> wrote:
> > 
> > > glen wrote:  
> > > \> Just thought I'd post a solution I came up with to finding  
> > > \> combinations (as in, permutations and combinations) of arrays. For  
> > > \> example, combining:
> > 
> > Juan, it would appear that glen posted this question/tip 3.5 years  
> > ago. Any reason you were responding to it now? (Which, in turn, lured  
> > me into responding. 🙂
> 
> Sure Gavin, I'm looking for something like that and found this post.  
> Maybe result useful to someone. You have another solution for this?  
> Thanks  
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

### Author: ![Juan\_Matias](https://avatars.discourse-cdn.com/v4/letter/j/c6cbf5/32.png) [@Juan\_Matias](https://rubytalk.org/u/Juan_Matias)
#### Post date: [8 June 2010 12:28 UTC](https://rubytalk.org/t/array-and-hash-combine-methods/33724/7 "2010-06-08T12:28:29Z")

</div>

Robert Klemme wrote:

> > > 
> > 
> > �[1,2].combine([3,4]).combine([5,6,7])  
> > � �end  
> > � �aux.map {|elem| elem.flatten }  
> > �end  
> > end
> 
> I'd rather do this:
> 
> module Enumerable  
> &nbsp;&nbsp;def combine(enum)  
> &nbsp;&nbsp;&nbsp;&nbsp;if block\_given?  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;each do |\*a|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enum.each do |\*b|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield \*a, \*b  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self  
> &nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enum\_for(:combine, enum)  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;end  
> end
> 
> [1,2].combine([3,4]) do |\*a|  
> &nbsp;&nbsp;p a  
> end
> 
> puts "--------------"
> 
> [1,2].combine([3,4]).each do |\*a|  
> &nbsp;&nbsp;p a  
> end
> 
> puts "--------------"
> 
> [1,2].combine([3,4]).combine([5,6]) do |\*a|  
> &nbsp;&nbsp;p a  
> end
> 
> puts "--------------"
> 
> [1,2].combine([3,4]).combine([5,6]).each do |\*a|  
> &nbsp;&nbsp;p a  
> end
> 
> Kind regards
> 
> robert

Great, I'll probe it,also I add a fix to my code:

class Array  
&nbsp;&nbsp;def combine(otherArray)  
&nbsp;&nbsp;&nbsp;&nbsp;aux =   
&nbsp;&nbsp;&nbsp;&nbsp;return otherArray if self.empty? #this line  
&nbsp;&nbsp;&nbsp;&nbsp;self.each do |self\_elem|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;otherArray.each do |other\_elem|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aux \<\< [self\_elem,other\_elem]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;aux.map {|elem| elem.flatten }  
&nbsp;&nbsp;end  
end

Juan Matias

> **···**
>
> > 2010/6/8 Juan Matias \<jmrepetti@gmail.com\>:
> 
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

### Author: ![Kamal\_Ahmed](https://avatars.discourse-cdn.com/v4/letter/k/4491bb/32.png) [@Kamal\_Ahmed](https://rubytalk.org/u/Kamal_Ahmed)
#### Post date: [8 June 2010 05:51 UTC](https://rubytalk.org/t/array-and-hash-combine-methods/33724/8 "2010-06-08T05:51:27Z")

</div>

The examples seem to be missing  
If there is code snippets, it would help.  
-Kamal.

> **···**
>
> \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> From: Juan Matias \<jmrepetti@gmail.com\>  
> To: ruby-talk ML \<ruby-talk@ruby-lang.org\>  
> Sent: Tue, June 8, 2010 12:33:24 AM  
> Subject: Re: array and hash combine methods
> 
> Gavin Kistner wrote:
> 
> > On Jun 7, 9:52�pm, Juan Matias \<jmrepe...@gmail.com\> wrote:
> > 
> > > glen wrote:  
> > > \> Just thought I'd post a solution I came up with to finding  
> > > \> combinations (as in, permutations and combinations) of arrays. For  
> > > \> example, combining:
> > 
> > Juan, it would appear that glen posted this question/tip 3.5 years  
> > ago. Any reason you were responding to it now? (Which, in turn, lured  
> > me into responding. 🙂
> 
> Sure Gavin, I'm looking for something like that and found this post.  
> Maybe result useful to someone. You have another solution for this?  
> Thanks  
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).
