split an array of hashes into an array of arrays of hashes

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

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__

: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 Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

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?

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

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!