# Splitting an array into sub\_arrays ...need advice

**URL:** <https://www.ruby-forum.com/t/splitting-an-array-into-sub-arrays-need-advice/90046>\
**Category:** Ruby\
**Created:** [March 25, 2007, 5:50pm UTC](https://www.ruby-forum.com/t/splitting-an-array-into-sub-arrays-need-advice/90046 "2007-03-25T17:50:38Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [March 25, 2007, 5:50pm UTC](https://www.ruby-forum.com/t/splitting-an-array-into-sub-arrays-need-advice/90046/1 "2007-03-25T17:50:38Z")

</div>

I have an array similar to this example (after sorting it on a[i][1]  
and a[i][2])

start\_array = [[1, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0], [4, 1, 2, 0],  
[5, 1, 2, 0], [6, 2, 1, 0], [7, 2, 1, 0], [8, 2, 2, 0], [9, 2, 2, 0],  
[10, 2, 3, 0] ]

I am trying to split it, into sub\_arrays according to similarelements  
a[i][1] and a[i][2] ,  
to get another array like this one :

resulting\_array = [[[1, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0]] ,  
[[4, 1, 2, 0], [5, 1, 2, 0]] , [[6, 2, 1, 0], [7, 2, 1, 0]] , [[8,  
2, 2, 1], [9, 2, 2, 0]] , [[10, 2, 3, 0]] ]

* * *

herafter is how I proceed… but I am not sure where I go… is it not  
too complicated (not even saying DRY…)

I am using a[i][3] as a counter, so I can change its value, before  
executing the splitting

0.step(start\_array.nitems-1, 1) do |i|  
start\_array[i][3] = 0  
end

then, I wrote this method

def count\_markers(a)  
n = 0  
0.step(a.nitems-2, 1) do |i|  
if (a[i][1] == a[i+1][1]) && (a[i][2] == a[i+1][2])  
n = n+1  
a[i][3] = n  
else  
a[i][3] = n +1  
n = 0  
end  
end  
a[a.nitems-1][3] = 1 if a[a.nitems-1][3] == 0  
end

so I get a count of the number of elements to put in each sub-array

counted\_array = count\_markers(start\_array)  
which gives me :  
counted\_array =\> [[1, 1, 1, 1], [2, 1, 1, 2], [3, 1, 1, 3], [4, 1, 2,  
1], [5, 1, 2, 2], [6, 2, 1, 1], [7, 2, 1, 2], [8, 2, 2, 1], [9, 2, 2,  
2], [10, 2, 3, 1] ]

now I don’t see how to split it to get the resulting array

resulting\_array = [[[1, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0]] ,  
[[4, 1, 2, 0], [5, 1, 2, 0]] , [[6, 2, 1, 0], [7, 2, 1, 0]] , [[8,  
2, 2, 1], [9, 2, 2, 0]] , [[10, 2, 3, 0]] ]  
where resulting\_array.nitems = 5

resulting\_array[0] = [[1, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0]] … and  
so on

---

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [March 25, 2007, 7:00pm UTC](https://www.ruby-forum.com/t/splitting-an-array-into-sub-arrays-need-advice/90046/2 "2007-03-25T19:00:48Z")

</div>

Le dimanche 25 mars 2007 17:50, Josselin a écrit :

> resulting\_array = [[[1, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0]] ,  
> [[4, 1, 2, 0], [5, 1, 2, 0]] , [[6, 2, 1, 0], [7, 2, 1, 0]] , [[8,  
> 2, 2, 1], [9, 2, 2, 0]] , [[10, 2, 3, 0]] ]

There is a way to group objects easily with Enumerable#partition\_by, in  
the  
Facets gem.

irb(main):001:0\> require ‘facets’  
irb(main):002:0\> require ‘enumerable/partition\_by’  
irb(main):006:0\> start\_array.partition\_by {|ary| ary[1…2]}  
=\> {[1, 2]=\>[[4, 1, 2, 0], [5, 1, 2, 0]], [2, 1]=\>[[6, 2, 1, 0], [7, 2,  
1,  
0]], [1, 1]=\>[[1, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0]], [2, 3]=\>[[10,  
2, 3,  
0]], [2, 2]=\>[[8, 2, 2, 0], [9, 2, 2, 0]]}

It may help you for what you are trying to do.

---

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [March 25, 2007, 10:01pm UTC](https://www.ruby-forum.com/t/splitting-an-array-into-sub-arrays-need-advice/90046/3 "2007-03-25T22:01:10Z")

</div>

On 2007-03-25 19:00:00 +0200, Olivier R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
said:

> > to get another array like this one :  
> > irb(main):002:0\> require ‘enumerable/partition\_by’  
> > irb(main):006:0\> start\_array.partition\_by {|ary| ary[1…2]}  
> > =\> {[1, 2]=\>[[4, 1, 2, 0], [5, 1, 2, 0]], [2, 1]=\>[[6, 2, 1, 0], [7,  
> > 2, 1,  
> > 0]], [1, 1]=\>[[1, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0]], [2, 3]=\>[[10,  
> > 2, 3,  
> > 0]], [2, 2]=\>[[8, 2, 2, 0], [9, 2, 2, 0]]}
> 
> It may help you for what you are trying to do.

thanks a lot I’ll have a look asap

---

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [March 25, 2007, 10:30pm UTC](https://www.ruby-forum.com/t/splitting-an-array-into-sub-arrays-need-advice/90046/4 "2007-03-25T22:30:13Z")

</div>

Note that partition\_by is a simple method with no dependencies. So, you  
can  
just copy/paste this method in your code from [facets.rubyforge.org](http://facets.rubyforge.org)  
online  
documentation. Here it is :

module Enumerable  
def partition\_by  
r = Hash.new{ |h,k| h[k]=[] }  
each do |e|  
r[yield(e)] \<\< e  
end  
return r  
end  
end

And then :

require ‘enumerator’  
start\_array.partition\_by {|ary| ary[1…2]}.to\_enum(:each\_value).to\_a

---

<div class="post-metadata">

**Author:** ![Josselin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@Josselin](https://www.ruby-forum.com/u/Josselin)\
**Post date:** [March 27, 2007, 5:51pm UTC](https://www.ruby-forum.com/t/splitting-an-array-into-sub-arrays-need-advice/90046/5 "2007-03-27T17:51:06Z")

</div>

On 2007-03-25 22:28:42 +0200, Olivier R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
said:

> ```
> return r
> 
> ```
> 
> end  
> end
> 
> And then :
> 
> require ‘enumerator’  
> start\_array.partition\_by {|ary| ary[1…2]}.to\_enum(:each\_value).to\_a

thanks a lot I got it
