Exiting .each early

M

Myrddin Emrys

I want to return part of a sorted array efficiently. The built in
iterators will search the entire array, but since I know it's sorted, I
only need to collect the items up until they stop being in range.
However, its pretty wasteful to keep iterating after they start to fall
out of range...

How do I break a .each (or .collect, .reject, etc) early?

For example:

#########################################################
class Item
attr_reader :level

def initialize
@level = rand(100)
end
end

list = Array.new(10) {Item.new}

list.sort {|a, b| a.level <=> b.level}

under50 = list.find {|item| item.level < 50} # wasteful!
#########################################################

Is there a simple way to do this? A rather complex solution would be to
create a routine to find the index where the transition from valid to
invalid occurred, and slice the array to that index... but just being
able to iterate over half of the items (rather than all) would be
efficient enough for me at this point.
 
R

Robert Klemme

I want to return part of a sorted array efficiently. The built in
iterators will search the entire array, but since I know it's sorted, I
only need to collect the items up until they stop being in range.
However, its pretty wasteful to keep iterating after they start to fall
out of range...

How do I break a .each (or .collect, .reject, etc) early?

Exactly with break. :)

irb(main):001:0> (1..10).each {|i| p i; break if i > 5}
1
2
3
4
5
6
=> nil
Is there a simple way to do this? A rather complex solution would be to
create a routine to find the index where the transition from valid to
invalid occurred, and slice the array to that index... but just being
able to iterate over half of the items (rather than all) would be
efficient enough for me at this point.

I rather suggest to use binary search. There is a library in RAA that
does it. Maybe there's also a gem.

Kind regards

robert
 
M

Myrddin Emrys

Robert said:
On 12.08.2008 18:51, Myrddin Emrys wrote:
Exactly with break. :)

For some reason I thought break wouldn't work in this context... stupid
me. I should have checked.
I rather suggest to use binary search. There is a library in RAA that
does it. Maybe there's also a gem.

I suspect so as well, but this particular application doesn't need it.
Really, it doesn't need to break early either (the arrays in question
are accessed frequently, but are under 100 items long), but for some
reason that inefficiency was really bothering me, regardless of its
actual impact. :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top