Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

extended foreach loop

1,086 views
Skip to first unread message

cody

unread,
May 28, 2004, 6:40:03 AM5/28/04
to
currently, foreach takes a IEnumerable as parameter, so we can do:

foreach (int i in array){}

what about an additional form of foreach that takes an IEnumerator as
parameter, so we can do:

foreach (int i in array.SkipIterator(2)) // get every 2nd item

or

foreach (int i in array.RangeIterator(2, 10)) // iterates items from 2 to 10

or

foreach (int i in array.ReverseIterator()) // iterates through items in
reverse order

or

foreach (int i in array.SafeIterator(typeof(int))) // iterates through all
items that are != null and are of type int

What do you think? I always wanted such a thing since foreach with iterators
are much better readable as a for loops and the intend is much clearer.

--
cody

Freeware Tools, Games and Humour
http://www.deutronium.de.vu || http://www.deutronium.tk


Alexander Muylaert

unread,
May 28, 2004, 8:12:01 AM5/28/04
to
Hi

I don't think so :-)

For Each means, for "each". That doesn't mean that you should be able to
skip items.

Kind regards

Alexander


Sami Vaaraniemi

unread,
May 28, 2004, 8:37:28 AM5/28/04
to

"Alexander Muylaert" <a...@hotmail.com> wrote in message
news:%23%23a1%23zKRE...@TK2MSFTNGP10.phx.gbl...

I think what cody is asking for is completely reasonable. I do not think,
however, that we should have language-level support for this since it is
(almost) trivial to implement it in terms of what we already have in the
language. E.g., (WARNING: UNTESTED CODE):

public class SkipEnumerator : IEnumerable, IEnumerator
{
IEnumerator ienumerator_;
int skip_;
bool start_ = true;

public SkipEnumerator(IEnumerable ienumerable, int skip)
{
ienumerator_ = ienumerable.GetEnumerator();
skip_ = skip;
}

#region IEnumerable

public IEnumerator GetEnumerator()
{
return this;
}

#endregion

#region IEnumerator

public bool MoveNext()
{
if (start_)
{
for (int i = 0; i < skip_; i++)
ienumerator_.MoveNext();
start_ = false;
}

return ienumerator_.MoveNext();
}

public object Current
{
get
{
return ienumerator_.Current;
}
}

public void Reset()
{
start_ = true;
ienumerator_.Reset();
}

#endregion
}

To use SkipEnumerator class, you write

int[] ints = new int[] { 1, 2, 3, 4, 5, 6, 7 };
foreach (int anInt in new SkipEnumerator(ints, 2))
{
Console.Write(anInt + " " );
}
// prints 3 4 5 6 7

RangeEnumerator and SafeEnumerator would be very similar to SkipEnumerator.
Implementing ReverseEnumerator in terms of just IEnumerator would require
two passes over the data as IEnumerator does not support moving backwards in
the data.

Regards,
Sami


Jon Skeet [C# MVP]

unread,
May 28, 2004, 8:31:42 AM5/28/04
to
cody <no_spam_d...@gmx.net> wrote:
> currently, foreach takes a IEnumerable as parameter, so we can do:
>
> foreach (int i in array){}
>
> what about an additional form of foreach that takes an IEnumerator as
> parameter, so we can do:
>
> foreach (int i in array.SkipIterator(2)) // get every 2nd item
>
> or
>
> foreach (int i in array.RangeIterator(2, 10)) // iterates items from 2 to 10
>
> or
>
> foreach (int i in array.ReverseIterator()) // iterates through items in
> reverse order
>
> or
>
> foreach (int i in array.SafeIterator(typeof(int))) // iterates through all
> items that are != null and are of type int
>
> What do you think? I always wanted such a thing since foreach with iterators
> are much better readable as a for loops and the intend is much clearer.

You could easily write your own class to do that though:

foreach (int i in new SkipIterator(array, 2))
{
}

foreach (int i in new SafeIterator(array, typeof(int)))
{
}

etc

--
Jon Skeet - <sk...@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

cody

unread,
May 28, 2004, 8:40:59 AM5/28/04
to
> I don't think so :-)
>
> For Each means, for "each". That doesn't mean that you should be able to
> skip items.


It also can mean: for each item that meats some condition.

cody

unread,
May 28, 2004, 8:47:49 AM5/28/04
to


A very good idea, I didn't think of that. An iterator which implements
IEnumerable AND IEnumerator!
That would solve my problem, and so there is indeed no need to imclude that
in the language specs.

> RangeEnumerator and SafeEnumerator would be very similar to
SkipEnumerator.
> Implementing ReverseEnumerator in terms of just IEnumerator would require
> two passes over the data as IEnumerator does not support moving backwards
in
> the data.

That is no problem, since internally the iterator can put out the data from
end to the beginning of the array.

Just a question: Which kind of convention is a trailing underscore for
private members? I only know conventions with leading _(_member) or leading
m_ (m_member).

Sami Vaaraniemi

unread,
May 28, 2004, 9:33:47 AM5/28/04
to

"cody" <no_spam_d...@gmx.net> wrote in message
news:%23ZlAgNL...@TK2MSFTNGP10.phx.gbl...

> Just a question: Which kind of convention is a trailing underscore for
> private members? I only know conventions with leading _(_member) or
leading
> m_ (m_member).
>

Oh, that's just a left-over from my C++ days. A trailing underscore was the
standard in a company I worked for many years. I don't like the 'm_' and 'm'
prefixes so I've kept the trailing underscore. I guess I should move on with
the rest of the world and change to leading underscore. Old habits die hard.

Sami


Daniel O'Connell [C# MVP]

unread,
May 28, 2004, 1:17:00 PM5/28/04
to

"Daniel Jin" <anon...@discussions.microsoft.com> wrote in message
news:430D9B37-09F3-436C...@microsoft.com...
>
> I read the C# 2.0 language spec a couple days ago. I believe that
> iterator will address exactly what you suggested. you can basicly use
> iterator in functions that return types that implement either IEnumerator
> or IEnumerable. in fact, there's a example in the spec that does a
> reverse iterator. you can easily do skip iterator and range iterator as
> well.

Yes, C# 2.0 iterators will be the best solution for this. C# iterators
should also allow for easy things like predicated enumeration wrappers, etc.

>
> ----- cody wrote: -----

Hilton

unread,
May 28, 2004, 2:30:27 PM5/28/04
to
Sami,

Underscores give me the chills. I prefer "this.skip = 10" - much easier on
the eyes and with VS, the "this" is highlighted and it becomes very easy to
figure out which variables are local or not. Also, when you type "this."
you get the popup menu.

Just MHO.

Hilton

"Sami Vaaraniemi" <samiva...@pleasejippii.fi> wrote in message
news:c97erh$bli$1...@phys-news1.kolumbus.fi...

0 new messages