I thought of a 3rd way, but I don't know if its too clever.

Basically, I can write one method, that takes a cond block as its
argument, and returns a class which defines "each" in terms of that
condition, and includes enumerable. Now I only have to write two
methods, and I can let Enumerable do the heavy lifting for me. Or is
that too clever/confusing?

Cheers,
Sam

Quoteing sroberts / uniserve.com, on Mon, Mar 31, 2003 at 01:19:59PM +0900:
> Kind of a general question.
> 
> If I have a container of objects, and people might want to iterate over
> particular sub-sets of those objects (all fields in a particular group,
> all fields with a particular title, etc.) I see two ways of doing  this:
> 
> 1 - I define an iterator, and yield to their callback:
> 
>   def each_by_group(group)
>     ... for all matches
>       yield(match)
>   end
> 
> 2 - I create an array of all the things I would call yield with, and
> return it:
> 
>   def array_of_group(group)
>    Array.new(all matches...)
>   end
> 
> 
> Pros and cons:
> 
> 1 is MUCH more efficient for large numbers of objects. With 2 I have to
> iterate over my internal array, collecting the objects for which the
> condition is true into a new array, and return it, potentially for the
> caller to use it temporarily, and then discard it to the GCer.
> 
> But...
> 
> if I do it myself, I feel like I'm going to replicate, eventually, all
> the methods in Enumerable for each order type that I can forsee, so why
> not just return an array, and let the caller deal with it using the
> Array methods they should already know?
> 
> What do other people do?
> 
> This seems like a general problem when you have a collection when there
> are multiple useful views, and subsets of that collection. My particular
> application is vCard decoding.
> 
> Thanks,
> Sam
> 
> 
>