From: Josh Cheek Date: 2011-01-15T20:39:37+09:00 Subject: Re: Normal For Loop --0016e64f47ce483fea0499e10157 Content-Type: text/plain; charset=ISO-8859-1 On Sat, Jan 15, 2011 at 3:52 AM, Saverio Miroddi wrote: > > I tried to do this the other night, but right now I can't find a good > > example so here it goes: > > > > a = some_array > > minValue = 999999 > > for(i=0; i > minValue = (5000 - a[i]).abs > > } > > > > > > This isn't the best example. However, there are many times like the > > loop above where I want to go through the whole thing, but if I find > > exactly what I am looking for, I want to bail out early instead of > > wasting that processing time. > > > > Also, I sometimes may want to not actually iterate straight through, but > > browse through the array in some more complex order. > > I have a "good" example. In my case I want to iterate a collection, > skipping a variable number of elements based on a given element. > In this case, the C for construct (counter_init, cycle_condition,) would > be useful because I wouldn't have to initialize the counter variable > outside of the scope, and I can increment the counter inside the loop. > > The code is something like this: > > for ( i = 0; i < elements.size; ) do > if elements[ i ].is_a?( OneType ) > do_operation( elements[ i ] ); > i += 1; > elsif elements[ i ].is_a?( AnotherType ) > sub_elements = [] > begin > sub_elements << elements[ i > i += 1; > end while elements[ i ].is_a?( AnotherType ) > do_another_operation( sub_elements ) > else > ... > end > end > > This example doesn't pretend to be clever/correct/well constructed, but > is a real-world case where this kind of loop would be useful. > > -- > Posted via http://www.ruby-forum.com/. > > It is probably unwise to put different types of data all in the same array, but here is my attempt (relies on 1.9 Enumerable method #chunk http://ruby-doc.org/core/classes/Enumerable.html#M001523) # these just record what params they received def do_operation(element) @do_operation ||= Array.new @do_operation << element end def do_another_operation(elements) @do_another_operation ||= Array.new @do_another_operation << elements end # sequences of Symbols should be considered a single element # and Fixnums should be considered a single element # (the data should probably not be stored like this) elements = [1,2,:a,:b,3,4,5,9,2,:a,:b] # chunk the data by its class chunks = elements.chunk(&:class) chunks.to_a # => [[Fixnum, [1, 2]], [Symbol, [:a, :b]], [Fixnum, [3, 4, 5, 9, 2]], [Symbol, [:a, :b]]] # look at each chunk, if they are fixnums, treat them individually # if they are symbols, treat them as a collection chunks.each do |klass,chunk| if Fixnum == klass chunk.each { |e| do_operation e } elsif Symbol == klass do_another_operation chunk else # ... end end # What did the methods receive? @do_operation # => [1, 2, 3, 4, 5, 9, 2] @do_another_operation # => [[:a, :b], [:a, :b]] --0016e64f47ce483fea0499e10157--