# Split an array of hashes into an array of arrays of hashes

**URL:** <https://www.ruby-forum.com/t/split-an-array-of-hashes-into-an-array-of-arrays-of-hashes/173323>\
**Category:** Rails\
**Created:** [August 6, 2009, 9:23pm UTC](https://www.ruby-forum.com/t/split-an-array-of-hashes-into-an-array-of-arrays-of-hashes/173323 "2009-08-06T21:23:29Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![nik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/6de8d8/32.png) [@nik](https://www.ruby-forum.com/u/nik)\
**Post date:** [August 6, 2009, 9:23pm UTC](https://www.ruby-forum.com/t/split-an-array-of-hashes-into-an-array-of-arrays-of-hashes/173323/1 "2009-08-06T21:23:29Z")

</div>

Hello, I have this big array of hashes:  
A =[h0, h1, h2, …, hn]  
some hi’s’ :cue key is true, others’ is false.  
e.g.,  
h1[:cue] = false  
h2[:cue] = false  
h3[:cue] = true  
h4[:cue] = false  
h5[:cue] = true  
…  
hn[:cue] = …

Again, these hashes are in an array, A.

Now, I’d like to group them into smaller arrays whose last item has a  
true cue  
so  
A’ = [[h1, h2, h3], [h4, h5], … , […] ]

Is there a built-in method to cook this up?  
If not, what combination of methods might you think would work most  
efficiently?

Thank You

---

<div class="post-metadata">

**Author:** ![nik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/6de8d8/32.png) [@nik](https://www.ruby-forum.com/u/nik)\
**Post date:** [August 7, 2009, 12:49am UTC](https://www.ruby-forum.com/t/split-an-array-of-hashes-into-an-array-of-arrays-of-hashes/173323/2 "2009-08-07T00:49:31Z")

</div>

On Aug 6, 2009, at 3:22 PM, Nik wrote:

> …  
> If not, what combination of methods might you think would work most  
> efficiently?
> 
> Thank You

Well, this seems to be a tasty dish. I took some liberty with your  
minimal spec, but you should see the first test for the usage that  
maps to your example.

#!/usr/bin/ruby -w  
class Array  
def split\_when  
result = [[]]  
each do |element|  
result[-1] \<\< element  
if block\_given? ? yield(element) : element  
result \<\< []  
end  
end  
result.pop if result.last.empty?  
result  
end  
end

if File.expand\_path($0) == File.expand\_path( **FILE** )  
require ‘test/unit’  
class SplitWhenTest \< Test::Unit::TestCase  
def setup  
h1 = { :cue =\> false }  
h2 = { :cue =\> false }  
h3 = { :cue =\> true }  
h4 = { :cue =\> false }  
h5 = { :cue =\> true }  
@ary = [h1, h2, h3, h4, h5]  
@expected = [[h1, h2, h3], [h4, h5] ]  
end

def test\_example\_from\_email  
assert\_equal @expected, @ary.split\_when {|e| e[:cue]}  
end

def test\_simple  
original = [ false, true, false, false, true, true, false,  
true, false, true, false ]  
expected = [[false, true],[false, false, true],[true],[false,  
true],[false, true],[false]]  
assert\_equal expected, original.split\_when, “no block”  
assert\_equal expected, original.split\_when {|e|e}, “simple block”  
end  
end  
end  
**END**

:code/ruby $ ./array\_split\_when.rb  
Loaded suite ./array\_split\_when  
Started  
…  
Finished in 0.000585 seconds.

2 tests, 3 assertions, 0 failures, 0 errors

-Rob

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![nik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/6de8d8/32.png) [@nik](https://www.ruby-forum.com/u/nik)\
**Post date:** [August 7, 2009, 5:06pm UTC](https://www.ruby-forum.com/t/split-an-array-of-hashes-into-an-array-of-arrays-of-hashes/173323/3 "2009-08-07T17:06:20Z")

</div>

Thanks Rob, in line 6 (where #!/usr/bin/ruby -w is line 1) where  
results[-1]\<\<element, is there a check to verify that the element’s  
cue is true and henceforth start a new and empty array?

---

<div class="post-metadata">

**Author:** ![nik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/6de8d8/32.png) [@nik](https://www.ruby-forum.com/u/nik)\
**Post date:** [August 9, 2009, 12:17am UTC](https://www.ruby-forum.com/t/split-an-array-of-hashes-into-an-array-of-arrays-of-hashes/173323/4 "2009-08-09T00:17:17Z")

</div>

Hey Rob,

Just got a very simple version to work. Based on your code

def self.split\_when(\*value)  
results = [[]]  
each do |element|  
results.last \<\< element  
if value.include?(element)  
results \<\< []  
end  
end  
results  
end

So, again, A = [h1, h2, h3, h4, h5, …, hn]  
and some for some hi, hi[:cue] = true.  
I then run

A.split\_when({:cue=\>true})

to get

[[h1,h2,h3], [h4, h5], … , [hj,…,hn] ]

Thanks again for the detailed code!

On Aug 7, 12:14 pm, Rob B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![nik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/6de8d8/32.png) [@nik](https://www.ruby-forum.com/u/nik)\
**Post date:** [August 7, 2009, 6:15pm UTC](https://www.ruby-forum.com/t/split-an-array-of-hashes-into-an-array-of-arrays-of-hashes/173323/5 "2009-08-07T18:15:26Z")

</div>

On Aug 7, 2009, at 11:05 AM, Nik wrote:

> Thanks Rob, in line 6 (where #!/usr/bin/ruby -w is line 1) where  
> results[-1]\<\<element, is there a check to verify that the element’s  
> cue is true and henceforth start a new and empty array?

No, but lines 7…9 do and line 11 discards the empty array when the  
last element was a cutoff (element[:cue] in this case) and was not  
needed to hold other elements.

-Rob

> > > h4[:cue] = false  
> > > A’ = [[h1, h2, h3], [h4, h5], … , […] ]
> > 
> > ```
> > result.pop if result.last.empty?
> > h3 = { :cue => true }
> > 
> > ```
> > 
> > def test\_simple  
> > **END**
> > 
> > :code/ruby $ ./array\_split\_when.rb  
> > Loaded suite ./array\_split\_when  
> > Started  
> > …  
> > Finished in 0.000585 seconds.
> > 
> > 2 tests, 3 assertions, 0 failures, 0 errors
> > 
> > -Rob

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid
