Counting from zero

nicolas cellier ncellier at ifrance.com
Tue May 2 07:42:03 UTC 2006


Le Mardi 02 Mai 2006 08:45, Duncan Mak a écrit :
> On 5/2/06, Duncan Mak <duncanmak at gmail.com> wrote:
> > However, I ran into trouble when I had to iterate two collections
> > together, but each at a different offset, i..e  matching a[i] to  b[i +
> > 2]. My solution in the end was to use a named let, which is not quite the
> > same as a for loop in C, but if I were writing this in Smalltalk I
> > wouldn't know how to do it with only do:, collect:, select:, etc either.
>

If you know very well that a and b are 1-based, i do not see any reason why 
not simply writing:

1 to: (a size min: b size - 2) do: [:i | (a at:i) doSomethingWith: (b at: 
i+2)].

Le Mardi 02 Mai 2006 08:52, Ralph Johnson a écrit :
> Probably you should use Streams.  If you think about this from a
> pattern point of view, internal iterators (do: and friends) are easier
> to use than external iterators (Stream and children) but external
> iterators are more powerful.  In particular, if you have to process
> several collections at once then you usually need to use Streams.  The
> Collection class has with:do:, which is sometimes enough to process
> two collections at a time, but the need to use several collections is
> a sign that you should think about Streams.
>
> -Ralph Johnson

True, the stream way is something more general, working whatever the keys used 
for accessing the SequenceableCollection a & b is. It is necessary to use 
them when you must write something more generic.
Just to illustrate Ralph's saying:

aStream := a readStream.
bStream := b readStream.
(bStream skip: 2) ifError: ['do something, b is too short'].
[aStream atEnd or: [b Stream atEnd]]
    [aStream next doSomethingWith: bStream next]

Same apply whatever the number of collections you iterate in parallel:

parallelCollections isEmpty ifFalse: [
parallelStreams := parallelCollections collect: [:e | e readStream].
[parallelStreams anySatisfy: [:e | e atEnd]]
    whileFalse: [(parallelStreams collect: [:e | e next]) doSomething]]

I do not think there is one Smalltalk way, there are many, depends on your 
requrements and style preferences...

Nicolas




More information about the Squeak-dev mailing list