The most idiomatic way to iterate through a Ruby array, exiting when an arbitrary condition met?
arrays, break, each, loops, ruby
Solution
`take` and `drop` have a variant `take_while` and `drop_while` where instead of providing a fixed number of elements you provide a block. Ruby will accumulate values from the receiver (in the case of take_while) as long as the block returns true. Your code could be rewritten as
array.take_while {|pair| pair.sum < foo}.map(&:sum)
This does mean that you calculate the sum of some of these pairs twice.
Problem
I want to iterate through an array, each element of which is an array of two integers (e.g. `[3,5]'); for each of these elements, I want to calculate the sum of the two integers, exiting the loop when any of these sums exceeds a certain arbitrary value. The source array is quite large, and I will likely find the desired value near the beginning, so looping through all of the unneeded elements is not a good option. I have written three loops to do this, all of which produce the desired result. My question is: which is more idiomatic Ruby? Or--better yet--is there a better way? I try not to use non-local loop variables in, but `break` statements look kind of hackish to my (admittedly novice) eye. ``` # Loop A pairs.each do |pair| pair_sum = pair.inject(:+) arr1 << pair_sum break if pair_sum > arr2.max end #Loop B - (just A condensed) pairs.each { |pair| arr1.last <= arr2.max ? arr1 << pair.inject(:+) : break } #Loop C i = 0 pair_sum = 0 begin pair_sum = pairs[i].inject(:+) arr1 << pair_sum i += 1 end until pair_sum > arr2.max ``` A similar question was asked at escaping the .each { } iteration early in Ruby, but the responses were essentially that, while using `.each` or `.each_with_index` and exiting with `break` when the target index was reached would work, `.take(num_elements).each` is more idiomatic. In my situation, however, I don't know in advance how many elements I'll have to iterate through, presenting me with what appears to be a boundary case. This is from a project Euler-type problem I've already solved, btw. Just wondering about the community-preferred syntax. Thanks in advance for your valuable time.