when iterating over a collection how to determine the current objects index

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
35 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: when iterating over a collection how to determine the current objects index

Marcus Denker-4

> On 13 Mar 2015, at 21:44, stepharo <[hidden email]> wrote:
>
>
>
> Le 10/3/15 14:40, Joachim Tuchel a écrit :
>> Marcus
>>  
>> So sorry for this false accusation. It is proprietary in Squeak.
>> And even if it was Dan's idea to rename it, I'd like to learn more about the reasoning.
>> My understanding would be:
>>  
>> #do: iterates over a collection
>> #doWithIndex: iterates over a collection and also keeps track of the current index.
>>  
>> Sounds very consistent to me. the most important thing I want the machine to do is iterate over the collection, and the index thing is just a variant thereof.
>>  
>> #do: iterates over a collection
>> #withIndexDo: keeps track of the index while iterating over a collection
>>  
>> Sounds clumsy to me. Introduces incompatibilities for not much value. If people complained about #do: as not intentioon revealing and opted to rename it to something like #withEachDo: , then I c
> +1
>

I think the reason was that there are withIndexCollect: , reverseWithIndexDo:,

And of course the real thing we learn: if you do something, do it for real and finish.

Now we have the problem: which version do we pick? We should pick one, rename the callers
and deprecate the other. In Pharo5. (#gather: is already on my list for that, too).

        Marcus


Reply | Threaded
Open this post in threaded view
|

Re: when iterating over a collection how to determine the current objects index

Sean P. DeNigris
Administrator
Marcus Denker-4 wrote
which version do we pick? We should pick one, rename the callers
As someone mentioned earlier in the thread, #doWithIndex: has the advantage of mirroring the argument order (although this still should be documented), and it's the one most people are probably most familiar with, so IMHO it makes sense to standardize on that.
Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: when iterating over a collection how to determine the current objects index

sebastianconcept@gmail.co
In reply to this post by Sanjay Minni
In such cases I might use a stream and monitor the `stream position` and iterate with

[ stream atEnd ] whileFalse: [
  item := stream next.
  stream position even ifTrue: [ self highlight: item ].
  .... ]

from mobile

> On 10/03/2015, at 09:11, Sanjay Minni <[hidden email]> wrote:
>
> Hi
>
> when iterating over a sequenced collection (array / ordered collection) how
> can I determine the current objects index value (without explicitly storing
> a counter or looking to match each time)
>
> Typically I need it:
> 1. to display a serial number when printing a report.
> 2. to determine if I am on the last element.
> 3. To highlight every n-th element.
>
> regards
> Sanjay
>
>
>
>
> -----
> ---
> Regards, Sanjay
> --
> View this message in context: http://forum.world.st/when-iterating-over-a-collection-how-to-determine-the-current-objects-index-tp4810920.html
> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
>

Reply | Threaded
Open this post in threaded view
|

Re: when iterating over a collection how to determine the current objects index

Nicolai Hess
In reply to this post by Sean P. DeNigris

2015-03-14 11:55 GMT+01:00 Sean P. DeNigris <[hidden email]>:
Marcus Denker-4 wrote
> which version do we pick? We should pick one, rename the callers

As someone mentioned earlier in the thread, #doWithIndex: has the advantage
of mirroring the argument order (although this still should be documented),
and it's the one most people are probably most familiar with, so IMHO it
makes sense to standardize on that.

I like withIndexDo: because code like

aCollection withIndexDo: aBlock
reads like
"a collection with index"  do



 



-----
Cheers,
Sean
--
View this message in context: http://forum.world.st/when-iterating-over-a-collection-how-to-determine-the-current-objects-index-tp4810920p4811848.html
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.


Reply | Threaded
Open this post in threaded view
|

Re: when iterating over a collection how to determine the current objects index

jtuchel
Nicolai,





Am 16.03.15 um 11:59 schrieb Nicolai Hess:

2015-03-14 11:55 GMT+01:00 Sean P. DeNigris <[hidden email]>:
Marcus Denker-4 wrote
> which version do we pick? We should pick one, rename the callers

As someone mentioned earlier in the thread, #doWithIndex: has the advantage
of mirroring the argument order (although this still should be documented),
and it's the one most people are probably most familiar with, so IMHO it
makes sense to standardize on that.

I like withIndexDo: because code like

so how would you name the current #do: if you had the choice?

I still think this looks very logical:

#do:
#do:separatedBy:
#doWithIndex:
#doWithSomeOtherSpecialty:andEvenMoreStuff:

And then there still ist the question if the order of the arguments should be changed:

today:

do: [:each| ]
doWithIndex: [:each :index| ]

future:

do: [:each| ]
withIndexDo: [:idx :each | ]

Do you really think that is better?

I think that if we move the withIndex part to the beginning of the message, it overstates the importance of the fact that we also need the index inside the iteration block.



aCollection withIndexDo: aBlock
reads like
"a collection with index"  do

This would make sense if it was a Collection with an Index. If there was an IndexedCollection class and maybe some message like asIndexedCollection or withIndex, which turns any collection into an IndexedCollection. Then the message might be a shortcut for "make thsi an indexed collection and iterate over it using its index" - comparable to Dictionary>>#keysAndValuesDo: - but please be aware that a Dictionary has keys and values by its very own nature. A Collection doesn't have an index (other than the fact that the elements are stored in some non-guarantueed order).


This may all sound quite picky, but I think this is plain wrong and you are about to introduce not only incompatible, but also misleading naming for methods that exist on all Smalltalk dialects.

Joachim



 



-----
Cheers,
Sean
--
View this message in context: http://forum.world.st/when-iterating-over-a-collection-how-to-determine-the-current-objects-index-tp4810920p4811848.html
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.




-- 
-----------------------------------------------------------------------
Objektfabrik Joachim Tuchel          [hidden email]
Fliederweg 1                         http://www.objektfabrik.de
D-71640 Ludwigsburg                  http://joachimtuchel.wordpress.com
Telefon: +49 7141 56 10 86 0         Fax: +49 7141 56 10 86 1

Reply | Threaded
Open this post in threaded view
|

Re: when iterating over a collection how to determine the current objects index

wernerk
Hi,
there are several methods that end with withBlaBla: aBlabla (ok, they
have generally several arguments). hence i would expect doWithIndex: to
have this form #doWithIndex: anIndex. and anything that ends with do:
expects a doBlock and several methods that have the form doSomething:
dont expect a block as argument. iow i find withIndexDo: more logical
than doWithIndex:
werner


Reply | Threaded
Open this post in threaded view
|

Fwd: when iterating over a collection how to determine the current objects index

Nicolai Hess
In reply to this post by jtuchel

---------- Forwarded message ----------
From: Nicolai Hess <[hidden email]>
Date: 2015-03-16 13:40 GMT+01:00
Subject: Re: [Pharo-users] when iterating over a collection how to determine the current objects index
To: "[hidden email]" <[hidden email]>



2015-03-16 12:19 GMT+01:00 [hidden email] <[hidden email]>:
Nicolai,





Am 16.03.15 um 11:59 schrieb Nicolai Hess:

2015-03-14 11:55 GMT+01:00 Sean P. DeNigris <[hidden email]>:
Marcus Denker-4 wrote
> which version do we pick? We should pick one, rename the callers

As someone mentioned earlier in the thread, #doWithIndex: has the advantage
of mirroring the argument order (although this still should be documented),
and it's the one most people are probably most familiar with, so IMHO it
makes sense to standardize on that.

I like withIndexDo: because code like

so how would you name the current #do: if you had the choice?

I still think this looks very logical:

#do:
#do:separatedBy:
#doWithIndex:
#doWithSomeOtherSpecialty:andEvenMoreStuff:

And then there still ist the question if the order of the arguments should be changed:

today:

do: [:each| ]
doWithIndex: [:each :index| ]

future:

do: [:each| ]
withIndexDo: [:idx :each | ]

Do you really think that is better?

I think that if we move the withIndex part to the beginning of the message, it overstates the importance of the fact that we also need the index inside the iteration block.



aCollection withIndexDo: aBlock
reads like
"a collection with index"  do

This would make sense if it was a Collection with an Index.

no, that is the point.
A collection with no index:
aCollection do:

A collection with no index, but iterator over it like it had one:
aCollection withIndex  do:

From the method comment:
withIndexDo: elementAndIndexBlock
    "Just like with:do: except that the iteration index supplies the second argument to the block."

it looks like this method derives from :

SequenceableCollection>>#with: otherCollection do: twoArgBlock
    "Evaluate twoArgBlock with corresponding elements from this collection and otherCollection."




 
If there was an IndexedCollection class and maybe some message like asIndexedCollection or withIndex, which turns any collection into an IndexedCollection. Then the message might be a shortcut for "make thsi an indexed collection and iterate over it using its index" - comparable to Dictionary>>#keysAndValuesDo: - but please be aware that a Dictionary has keys and values by its very own nature. A Collection doesn't have an index (other than the fact that the elements are stored in some non-guarantueed order).


This may all sound quite picky, but I think this is plain wrong and you are about to introduce not only incompatible, but also misleading naming for methods that exist on all Smalltalk dialects.


I don't want to rename it, it is already there. I just said I like the one better than the other one.
But it is not really important, I am fine  with either or both. This was just my explanation why I would choose withIndexDo:

 

Joachim



 



-----
Cheers,
Sean
--
View this message in context: http://forum.world.st/when-iterating-over-a-collection-how-to-determine-the-current-objects-index-tp4810920p4811848.html
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.




-- 
-----------------------------------------------------------------------
Objektfabrik Joachim Tuchel          [hidden email]
Fliederweg 1                         http://www.objektfabrik.de
D-71640 Ludwigsburg                  http://joachimtuchel.wordpress.com
Telefon: +49 7141 56 10 86 0         Fax: +49 7141 56 10 86 1



Reply | Threaded
Open this post in threaded view
|

Re: Fwd: when iterating over a collection how to determine the current objects index

jtuchel
Nicolai,

I think you are comparing apples and oranges here.

AFAIK with:do: uses a second collection as first parameter and iterates over both of them. That's a completely different meaning of "with", imo. Let's not get started on the many ways in which with:do: is badly named ;-)

I agree we can end this discussion as it is. I have two main arguments against renaming doWithIndex: one of which is that it would make Pharo just a little more incompatible with other dialects and one based on my guts about the name itself. This will not lead anywhere ;-)

Joachim



Am 16.03.15 um 13:41 schrieb Nicolai Hess:

---------- Forwarded message ----------
From: Nicolai Hess <[hidden email]>
Date: 2015-03-16 13:40 GMT+01:00
Subject: Re: [Pharo-users] when iterating over a collection how to determine the current objects index
To: "[hidden email]" <[hidden email]>



2015-03-16 12:19 GMT+01:00 [hidden email] <[hidden email]>:
Nicolai,





Am 16.03.15 um 11:59 schrieb Nicolai Hess:

2015-03-14 11:55 GMT+01:00 Sean P. DeNigris <[hidden email]>:
Marcus Denker-4 wrote
> which version do we pick? We should pick one, rename the callers

As someone mentioned earlier in the thread, #doWithIndex: has the advantage
of mirroring the argument order (although this still should be documented),
and it's the one most people are probably most familiar with, so IMHO it
makes sense to standardize on that.

I like withIndexDo: because code like

so how would you name the current #do: if you had the choice?

I still think this looks very logical:

#do:
#do:separatedBy:
#doWithIndex:
#doWithSomeOtherSpecialty:andEvenMoreStuff:

And then there still ist the question if the order of the arguments should be changed:

today:

do: [:each| ]
doWithIndex: [:each :index| ]

future:

do: [:each| ]
withIndexDo: [:idx :each | ]

Do you really think that is better?

I think that if we move the withIndex part to the beginning of the message, it overstates the importance of the fact that we also need the index inside the iteration block.



aCollection withIndexDo: aBlock
reads like
"a collection with index"  do

This would make sense if it was a Collection with an Index.

no, that is the point.
A collection with no index:
aCollection do:

A collection with no index, but iterator over it like it had one:
aCollection withIndex  do:

From the method comment:
withIndexDo: elementAndIndexBlock
    "Just like with:do: except that the iteration index supplies the second argument to the block."

it looks like this method derives from :

SequenceableCollection>>#with: otherCollection do: twoArgBlock
    "Evaluate twoArgBlock with corresponding elements from this collection and otherCollection."




 
If there was an IndexedCollection class and maybe some message like asIndexedCollection or withIndex, which turns any collection into an IndexedCollection. Then the message might be a shortcut for "make thsi an indexed collection and iterate over it using its index" - comparable to Dictionary>>#keysAndValuesDo: - but please be aware that a Dictionary has keys and values by its very own nature. A Collection doesn't have an index (other than the fact that the elements are stored in some non-guarantueed order).


This may all sound quite picky, but I think this is plain wrong and you are about to introduce not only incompatible, but also misleading naming for methods that exist on all Smalltalk dialects.


I don't want to rename it, it is already there. I just said I like the one better than the other one.
But it is not really important, I am fine  with either or both. This was just my explanation why I would choose withIndexDo:

 

Joachim



 



-----
Cheers,
Sean
--
View this message in context: http://forum.world.st/when-iterating-over-a-collection-how-to-determine-the-current-objects-index-tp4810920p4811848.html
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.




-- 
-----------------------------------------------------------------------
Objektfabrik Joachim Tuchel          [hidden email]
Fliederweg 1                         http://www.objektfabrik.de
D-71640 Ludwigsburg                  http://joachimtuchel.wordpress.com
Telefon: +49 7141 56 10 86 0         Fax: +49 7141 56 10 86 1





-- 
-----------------------------------------------------------------------
Objektfabrik Joachim Tuchel          [hidden email]
Fliederweg 1                         http://www.objektfabrik.de
D-71640 Ludwigsburg                  http://joachimtuchel.wordpress.com
Telefon: +49 7141 56 10 86 0         Fax: +49 7141 56 10 86 1

Reply | Threaded
Open this post in threaded view
|

Re: when iterating over a collection how to determine the current objects index

stepharo
In reply to this post by jtuchel
so may be we should open a bug entry and make sure that
doWithIndex: is used in the system.
no?

Le 16/3/15 12:19, [hidden email] a écrit :
Nicolai,





Am 16.03.15 um 11:59 schrieb Nicolai Hess:

2015-03-14 11:55 GMT+01:00 Sean P. DeNigris <[hidden email]>:
Marcus Denker-4 wrote
> which version do we pick? We should pick one, rename the callers

As someone mentioned earlier in the thread, #doWithIndex: has the advantage
of mirroring the argument order (although this still should be documented),
and it's the one most people are probably most familiar with, so IMHO it
makes sense to standardize on that.

I like withIndexDo: because code like

so how would you name the current #do: if you had the choice?

I still think this looks very logical:

#do:
#do:separatedBy:
#doWithIndex:
#doWithSomeOtherSpecialty:andEvenMoreStuff:

And then there still ist the question if the order of the arguments should be changed:

today:

do: [:each| ]
doWithIndex: [:each :index| ]

future:

do: [:each| ]
withIndexDo: [:idx :each | ]

Do you really think that is better?

I think that if we move the withIndex part to the beginning of the message, it overstates the importance of the fact that we also need the index inside the iteration block.



aCollection withIndexDo: aBlock
reads like
"a collection with index"  do

This would make sense if it was a Collection with an Index. If there was an IndexedCollection class and maybe some message like asIndexedCollection or withIndex, which turns any collection into an IndexedCollection. Then the message might be a shortcut for "make thsi an indexed collection and iterate over it using its index" - comparable to Dictionary>>#keysAndValuesDo: - but please be aware that a Dictionary has keys and values by its very own nature. A Collection doesn't have an index (other than the fact that the elements are stored in some non-guarantueed order).


This may all sound quite picky, but I think this is plain wrong and you are about to introduce not only incompatible, but also misleading naming for methods that exist on all Smalltalk dialects.

Joachim



 



-----
Cheers,
Sean
--
View this message in context: http://forum.world.st/when-iterating-over-a-collection-how-to-determine-the-current-objects-index-tp4810920p4811848.html
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.




-- 
-----------------------------------------------------------------------
Objektfabrik Joachim Tuchel          [hidden email]
Fliederweg 1                         http://www.objektfabrik.de
D-71640 Ludwigsburg                  http://joachimtuchel.wordpress.com
Telefon: +49 7141 56 10 86 0         Fax: +49 7141 56 10 86 1


Reply | Threaded
Open this post in threaded view
|

Re: when iterating over a collection how to determine the current objects index

philippeback
In reply to this post by Nicolai Hess


Le 16 mars 2015 11:59, "Nicolai Hess" <[hidden email]> a écrit :
>
>
> 2015-03-14 11:55 GMT+01:00 Sean P. DeNigris <[hidden email]>:
>>
>> Marcus Denker-4 wrote
>> > which version do we pick? We should pick one, rename the callers
>>
>> As someone mentioned earlier in the thread, #doWithIndex: has the advantage
>> of mirroring the argument order (although this still should be documented),
>> and it's the one most people are probably most familiar with, so IMHO it
>> makes sense to standardize on that.
>
>
> I like withIndexDo: because code like
>
> aCollection withIndexDo: aBlock
> reads like
> "a collection with index"  do
>

I like things ending with do: as they are easy to spot. And you know that is coming next is a block most of the time.

Not so with doWithIndex:

e.g.

someObject mongoDo: [ ... ].

reads better than

someObject doWithMongo: [ ].

especially when there are things like

mongoDo:
mongoCachedCollectionsDo:
aggregateDo:

and so on.

This is the same story with

... readStreamDo: [  ]

withIndexDo: obeys the principle of least astonishment to me.

Phil

>
>
>  
>>
>>
>>
>>
>> -----
>> Cheers,
>> Sean
>> --
>> View this message in context: http://forum.world.st/when-iterating-over-a-collection-how-to-determine-the-current-objects-index-tp4810920p4811848.html
>> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: when iterating over a collection how to determine the current objects index

philippeback
In reply to this post by sebastianconcept@gmail.co


Le 14 mars 2015 12:16, "Sebastian Sastre" <[hidden email]> a écrit :
>
> In such cases I might use a stream and monitor the `stream position` and iterate with
>
> [ stream atEnd ] whileFalse: [
>   item := stream next.
>   stream position even ifTrue: [ self highlight: item ].
>   .... ]
>

Exactly!

Streams and collections are perfect for that.

And they can even do:

ReadStream class >> on:from:to:

or upTo: etc.

Phil

> from mobile
>
> > On 10/03/2015, at 09:11, Sanjay Minni <[hidden email]> wrote:
> >
> > Hi
> >
> > when iterating over a sequenced collection (array / ordered collection) how
> > can I determine the current objects index value (without explicitly storing
> > a counter or looking to match each time)
> >
> > Typically I need it:
> > 1. to display a serial number when printing a report.
> > 2. to determine if I am on the last element.
> > 3. To highlight every n-th element.
> >
> > regards
> > Sanjay
> >
> >
> >
> >
> > -----
> > ---
> > Regards, Sanjay
> > --
> > View this message in context: http://forum.world.st/when-iterating-over-a-collection-how-to-determine-the-current-objects-index-tp4810920.html
> > Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
> >
>
>

Reply | Threaded
Open this post in threaded view
|

Re: when iterating over a collection how to determine the current objects index

Sean P. DeNigris
Administrator
In reply to this post by philippeback

e.g. someObject mongoDo: [ ... ].

withIndexDo: obeys the principle of least astonishment to me.

Except the difference between this case and the other examples is that "withIndex + Do:" reverses the argument order (:e :i).

But more importantly, GNU and other Smalltalks have #doWithIndex:. I don’t think that the payoff here is enough to diverge from the rest of the world.

Lastly, apparently e.g. Dolphin has removed it completely in favor of #keysAndValuesDo: in response to a change in the ANSI standard. From http://forum.world.st/doWithIndex-tp3374968p3374975.html :
#doWithIndex: was in an early ANSI draft, presumably 
proposed by one of IBM's representatives but I can't really remember, and we 
had it in the version of Dolphin current at the time. Later it was removed 
from the standard and replaced with #keysAndValuesDo:, which makes sense 
since a sequenced collection can legimitately represent a "keyed collection" 
with integer keys. Therefore there is no need for a second enumerator that 
does the same thing but with key and value reversed.

Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: when iterating over a collection how to determine the current objects index

Nicolai Hess


2015-03-18 22:55 GMT+01:00 Sean P. DeNigris <[hidden email]>:

e.g. someObject mongoDo: [ ... ].

withIndexDo: obeys the principle of least astonishment to me.

Except the difference between this case and the other examples is that "withIndex + Do:" reverses the argument order (:e :i).

No, the argument order is perfectly right :)
aCollection withIndexDo:  == "for each collection element 'e' with index 'i' do: [:e :i | ....]"  



 

But more importantly, GNU and other Smalltalks have #doWithIndex:. I don’t think that the payoff here is enough to diverge from the rest of the world.

Lastly, apparently e.g. Dolphin has removed it completely in favor of #keysAndValuesDo: in response to a change in the ANSI standard. From http://forum.world.st/doWithIndex-tp3374968p3374975.html :
#doWithIndex: was in an early ANSI draft, presumably 
proposed by one of IBM's representatives but I can't really remember, and we 
had it in the version of Dolphin current at the time. Later it was removed 
from the standard and replaced with #keysAndValuesDo:, which makes sense 
since a sequenced collection can legimitately represent a "keyed collection" 
with integer keys. Therefore there is no need for a second enumerator that 
does the same thing but with key and value reversed.

Cheers,
Sean


View this message in context: Re: when iterating over a collection how to determine the current objects index
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

Re: when iterating over a collection how to determine the current objects index

jfabry
In reply to this post by Sean P. DeNigris

Actually, using keysAndValuesDo: makes a lot of sense to me and seems to be a nice and clean way to resolve this discussion. I really like that it’s nicely polymorphic if we consider the keys of a sequenced collection to be the indexes. I just like this kind of simplicity … 

On Mar 18, 2015, at 18:55, Sean P. DeNigris <[hidden email]> wrote:

Lastly, apparently e.g. Dolphin has removed it completely in favor of #keysAndValuesDo: in response to a change in the ANSI standard. From http://forum.world.st/doWithIndex-tp3374968p3374975.html :
#doWithIndex: was in an early ANSI draft, presumably 
proposed by one of IBM's representatives but I can't really remember, and we 
had it in the version of Dolphin current at the time. Later it was removed 
from the standard and replaced with #keysAndValuesDo:, which makes sense 
since a sequenced collection can legimitately represent a "keyed collection" 
with integer keys. Therefore there is no need for a second enumerator that 
does the same thing but with key and value reversed.




---> Save our in-boxes! http://emailcharter.org <---

Johan Fabry   -   http://pleiad.cl/~jfabry
PLEIAD lab  -  Computer Science Department (DCC)  -  University of Chile

Reply | Threaded
Open this post in threaded view
|

Re: when iterating over a collection how to determine the current objects index

Peter Uhnak
keysAndValuesDo:
+1

this is also what Dictionary use. 

Peter
12