By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,851 Members | 1,022 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,851 IT Pros & Developers. It's quick & easy.

best way to enumerate List<> & remove unwanted elements?

P: n/a
Obviously you can't just use a simple for loop, since you may skip
over elements.

You could modify the loop counter each time an element is deleted.
But, the loop ending condition must be checked on each iteration,
since the Count changes as you delete elements. I would think it is
guaranteed to be computed each time, and not cached.

So, is this the best way?

List<intmylist = .......something......;
for (int i=0; i<mylist.Count; i++) {
if (want_to_remove) {
mylist.RemoveAt(i);
i--;
}
}

Zytan

May 13 '07 #1
Share this Question
Share on Google+
56 Replies


P: n/a
No, it isn't. To make it easier, you really should enumerate from the
end of the list. This way, you don't have to play around with the index
variable (in this case, i).
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Zytan" <zy**********@gmail.comwrote in message
news:11**********************@u30g2000hsc.googlegr oups.com...
Obviously you can't just use a simple for loop, since you may skip
over elements.

You could modify the loop counter each time an element is deleted.
But, the loop ending condition must be checked on each iteration,
since the Count changes as you delete elements. I would think it is
guaranteed to be computed each time, and not cached.

So, is this the best way?

List<intmylist = .......something......;
for (int i=0; i<mylist.Count; i++) {
if (want_to_remove) {
mylist.RemoveAt(i);
i--;
}
}

Zytan

May 13 '07 #2

P: n/a
No, it isn't. To make it easier, you really should enumerate from the
end of the list. This way, you don't have to play around with the index
variable (in this case, i).
Ok. Enumerate with a for loop? And the automatic i-- each time is
sufficient for not skipping elements, I see. Thanks.

(I believe my solution still works, though, right? It's just not the
best way.)

Zytan

May 13 '07 #3

P: n/a

"Zytan" <zy**********@gmail.comwrote in message
news:11**********************@u30g2000hsc.googlegr oups.com...
Obviously you can't just use a simple for loop, since you may skip
over elements.

You could modify the loop counter each time an element is deleted.
But, the loop ending condition must be checked on each iteration,
since the Count changes as you delete elements. I would think it is
guaranteed to be computed each time, and not cached.

So, is this the best way?

List<intmylist = .......something......;
for (int i=0; i<mylist.Count; i++) {
if (want_to_remove) {
mylist.RemoveAt(i);
i--;
}
}
No, you don't decrement (i) like that, you're going to eventually blow up at
that RemoveAt(i).

You just want to do mylist.Clear if you just want to *clear* all elements
out of the list, if that's what you're trying to do.

May 14 '07 #4

P: n/a
Another option is to use RemoveAll(...) with a predicate, perhaps
inline.

Marc

May 14 '07 #5

P: n/a
On Sun, 13 May 2007 16:06:36 -0700, Zytan <zy**********@gmail.comwrote:
Obviously you can't just use a simple for loop, since you may skip
over elements.

You could modify the loop counter each time an element is deleted.
But, the loop ending condition must be checked on each iteration,
since the Count changes as you delete elements. I would think it is
guaranteed to be computed each time, and not cached.

So, is this the best way?
I like Marc's suggestion, to use a predicate delegate to control removal..
It seems tailor-made to the exact scenario you're asking about.

Note that if efficiency is of concern, you may prefer to actually generate
a whole new List<instance instead, copying over only the values you want
to the new List<>. The reason being that, if I recall correctly, the
List<implementation uses an array, and insertions and removals in the
array require shifting the contents of the array. In other words, even if
you start at the end, removing elements one at a time involves copying on
average half of the array for each removal.

If you're removing a large percentage of the elements, and you start at
the end of the list, this will help by ensuring that you're shifting the
minimal number of elements with each removal. But you still have the
shift. If you're willing to create a new copy of the List<>, then you can
preallocate the List<to be as large as is necessary to ensure no
reallocations during the processing, and then if you're concerned about
wasted memory once you're done, trim the List<>.

The docs *claim* that RemoveAll() is O(n). So it's possible that
internally, it does exactly what I describe above. It's hard to see how,
if the List<implementation really is an array, it could be O(n)
otherwise. But there's a bunch of assumptions in the first part of this
paragraph, so if you really care it seems to me you should probably do
some direct tests between the various methods (and in particular, doing
your own copy-based algorithm vs using RemoveAll()).

If it's not that important (and frankly, it probably isn't until you have
proven to yourself that this part of the code is important for performance
in your application overall), then you should probably just use
RemoveAll() and trust the docs. :)

Finally, note that at the very least I don't see any point in incrementing
a counter that you've just decremented. While the algorithm you posted
could be greatly improved as already mentioned, at a minimum it seems to
me it should look more like this:

List<intmylist = /* whatever */;
int i = 0;

while (i < mylist.Count)
{
if (want_to_remove)
{
mylist.RemoveAt(i);
}
else
{
i++;
}
}

Pete
May 14 '07 #6

P: n/a
No, you don't decrement (i) like that, you're going to eventually blow up at
that RemoveAt(i).
Why? I think it works. Remember the loop increments i itself, so
afte a remove, and decrement, and increment, i is the same value. The
loop code should jump out when there are no elements left.
You just want to do mylist.Clear if you just want to *clear* all elements
out of the list, if that's what you're trying to do.
No, that's not what I am trying to do. I thought my code was clear.
I want to enumerate all elements and remove some based on some
criteria. Perhaps all will be removed, perhaps none, likely only
some.

Zytan

May 14 '07 #7

P: n/a
Another option is to use RemoveAll(...) with a predicate, perhaps
inline.
Interesting, I didn't even know that existed. Thanks, Marc. I think
this is the best method, although it moves the criterion code into
another function (which may be desired if it was complex).

Zytan
May 14 '07 #8

P: n/a
I like Marc's suggestion, to use a predicate delegate to control removal.
It seems tailor-made to the exact scenario you're asking about.
Yes, it does.
Note that if efficiency is of concern
[snip great explanation]
I totally agree. But, efficiency is not a concern, and the list is
small (10's of elements). And yes, even if it was bigger, I shouldn't
care about it until I know it's a bottleneck.

I am also interesting in List<>'s internals. I don't think the docs
lie. Perhaps a look into the C++ STL implementation would reveal some
information about how it can act like an array, and be fast for
modification at the same time. I don't have the time ATM to look this
up.
Finally, note that at the very least I don't see any point in incrementing
a counter that you've just decremented.
Agreed. I like your code better. Don't know why I didn't think about
that.
While the algorithm you posted
could be greatly improved as already mentioned, at a minimum it seems to
me it should look more like this:
Pete, does my algorithm, however bad it is, work? I am 99% sure it
does, but people doubt it.

Zytan

May 14 '07 #9

P: n/a
On Mon, 14 May 2007 10:37:29 -0700, Zytan <zy**********@gmail.comwrote:
[...]
Pete, does my algorithm, however bad it is, work? I am 99% sure it
does, but people doubt it.
I only saw one post doubting it, and I suspect he simply misread the
code. I've been known to do the same from time to time. :)
May 14 '07 #10

P: n/a
I only saw one post doubting it, and I suspect he simply misread the
code. I've been known to do the same from time to time. :)
Ok, thanks :)

I've updated all my code with the delegate, anyway. Much better!

Zytan

May 14 '07 #11

P: n/a
although it moves the criterion code into
another function (which may be desired if it was complex).
If complex, then yes - perhaps move into another function; however,
note that you can also
do this inline (as mentioned), which can actually make it easier to
use arguments, since
they will be "captured" into the inline method.

For instance:

List<intvalues = ...
int keepThoseDivisibleBy = 4; // could be a parameter
values.RemoveAll(delegate (int value) {
// return true to remove, i.e. those *not* divisible
return value % keepThoseDivisibleBy != 0;
});

A dubious example, but useful for lots of scenarios,
e.g. string matching (eitherusing index-of, or perhaps compile
a Regex and test each in turn).

This should presumably get even easier when we have lambdas...
I'm hoping that I can do something like (forgive the syntax; my C#3.0
isn't too hot yet):

values.RemoveAll(value =value % keepThoseDivisibleBy != 0);

Marc

May 14 '07 #12

P: n/a

"Zytan" <zy**********@gmail.comwrote in message
news:11**********************@u30g2000hsc.googlegr oups.com...
>No, you don't decrement (i) like that, you're going to eventually blow up
at
that RemoveAt(i).

Why? I think it works. Remember the loop increments i itself, so
afte a remove, and decrement, and increment, i is the same value. The
loop code should jump out when there are no elements left.
It's been my experience with addressing an element in a loop with a
RemoveAt(i) is trouble, because the number of (i) may not be there when you
think it is suppose to be there.

I would be doing it from another function and have (i) predetermined knowing
for sure that (i) is a valid element index and would be calling a function
to do the RemoveAt(i).

You should be passing and index to RemoveAt(i) for a known predetermined
element index and not off of some in-line loop on the fly. But that's just
me.
May 14 '07 #13

P: n/a
On Mon, 14 May 2007 13:05:56 -0700, Mr. Arnold <MR. <Ar****@Arnold.com>>
wrote:
[...]
You should be passing and index to RemoveAt(i) for a known predetermined
element index and not off of some in-line loop on the fly. But that's
just me.
While I'm not defending the overall style of that loop, what makes you
suggest that the index he's removing is NOT "a known predetermined element
index"? At the point in that code, the index "i" is guaranteed to be no
less than 0 but less than the total number of elements in the array. In
other words, within the legal values for array indexes for his list.
"mylist.Count" is reevaluated each time through the loop, and so the loop
will never be entered unless it is possible to successfully remove the
element at position "i".

Pete
May 14 '07 #14

P: n/a
While I'm not defending the overall style of that loop, what makes you
suggest that the index he's removing is NOT "a known predetermined element
index"? At the point in that code, the index "i" is guaranteed to be no
less than 0 but less than the total number of elements in the array. In
other words, within the legal values for array indexes for his list.
"mylist.Count" is reevaluated each time through the loop, and so the loop
will never be entered unless it is possible to successfully remove the
element at position "i".
Yes, exactly. Only if I were multi-threading would the code
potentially be fatal. And in that case, I could use a lock around the
whole thing to ensure the mylist.Count is still valid by the time I go
and use "i".

Zytan.

May 14 '07 #15

P: n/a
For instance:
>
List<intvalues = ...
int keepThoseDivisibleBy = 4; // could be a parameter
values.RemoveAll(delegate (int value) {
// return true to remove, i.e. those *not* divisible
return value % keepThoseDivisibleBy != 0;
});
Oh, that's what you meant by inline! yes, I have seen that before,
that's cool. thanks for the idea. My code is complex enough that it
warrants another function, so it was fine.

Zytan

May 14 '07 #16

P: n/a
On Mon, 14 May 2007 14:50:58 -0700, Zytan <zy**********@gmail.comwrote:
Yes, exactly. Only if I were multi-threading would the code
potentially be fatal. And in that case, I could use a lock around the
whole thing to ensure the mylist.Count is still valid by the time I go
and use "i".
And if you were multi-threading, moving the call to RemoveAll() into a
separate method wouldn't change things. You'd still need to lock the list
before messing with it.
May 14 '07 #17

P: n/a
And if you were multi-threading, moving the call to RemoveAll() into a
separate method wouldn't change things. You'd still need to lock the list
before messing with it.
Yes, that's right. What is does is not an atomic operation, and it
couldn't possibly hope to lock the data from anyone else who may try
to access it. That's up to you.

Zytan

May 14 '07 #18

P: n/a

"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Mon, 14 May 2007 13:05:56 -0700, Mr. Arnold <MR. <Ar****@Arnold.com>>
wrote:
>[...]
You should be passing and index to RemoveAt(i) for a known predetermined
element index and not off of some in-line loop on the fly. But that's
just me.

While I'm not defending the overall style of that loop, what makes you
suggest that the index he's removing is NOT "a known predetermined element
index"?
I don't like the loop in this case, because I have been in that loop doing
RemoveAt(i) and watched it go down.

May 14 '07 #19

P: n/a
On Mon, 14 May 2007 16:05:06 -0700, Mr. Arnold <MR. <Ar****@Arnold.com>>
wrote:
>While I'm not defending the overall style of that loop, what makes you
suggest that the index he's removing is NOT "a known predetermined
element index"?

I don't like the loop in this case, because I have been in that loop
doing RemoveAt(i) and watched it go down.
Well, you must have had a different bug then.

It's true that there are other reasons not to loop that way, and one of
those reasons is the likelihood of creating new bugs that cause problems.
But the code posted doesn't have any problems with correctness.

Pete
May 14 '07 #20

P: n/a

"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Mon, 14 May 2007 16:05:06 -0700, Mr. Arnold <MR. <Ar****@Arnold.com>>
wrote:
>>While I'm not defending the overall style of that loop, what makes you
suggest that the index he's removing is NOT "a known predetermined
element index"?

I don't like the loop in this case, because I have been in that loop
doing RemoveAt(i) and watched it go down.

Well, you must have had a different bug then.

It's true that there are other reasons not to loop that way, and one of
those reasons is the likelihood of creating new bugs that cause problems.
But the code posted doesn't have any problems with correctness.
Don't you know? It's MS and what works up in the IDE and what works when you
deploy it are two different things. I have been there an done that. :)

May 15 '07 #21

P: n/a
On Mon, 14 May 2007 17:37:59 -0700, Mr. Arnold <MR. <Ar****@Arnold.com>>
wrote:
Don't you know? It's MS and what works up in the IDE and what works when
you deploy it are two different things. I have been there an done that.
:)
No, I don't know. If it is possible that the code that was posted would
somehow stop working when it's deployed, it's not because of the way the
loop is written.
May 15 '07 #22

P: n/a

"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Mon, 14 May 2007 17:37:59 -0700, Mr. Arnold <MR. <Ar****@Arnold.com>>
wrote:
>Don't you know? It's MS and what works up in the IDE and what works when
you deploy it are two different things. I have been there an done that.
:)

No, I don't know. If it is possible that the code that was posted would
somehow stop working when it's deployed, it's not because of the way the
loop is written.
This is beyond the whole little loop function. I am surprised that you don't
understand the statement above that I made.

How long have you been programming with MS solutions not to know that what
happens in development or the test environments may not hold true when a
solution hit's out there in the production environment?

You ever had to go out to a production server and debug code that worked
perfectly in development and test environments but not in production?

May 15 '07 #23

P: n/a
On Mon, 14 May 2007 20:06:54 -0700, Mr. Arnold <MR. <Ar****@Arnold.com>>
wrote:
This is beyond the whole little loop function. I am surprised that you
don't understand the statement above that I made.
You wrote:

"No, you don't decrement (i) like that, you're going to eventually blow up
at that RemoveAt(i)"

That statement is simply false. But, if you're going to assert that it is
true because .NET is buggy, then the conclusion ("you're going to
eventually blow up") has nothing at all to do with the exposition ("you
don't decrement (i) like that").

Either way, there is nothing wrong at all with the code that was posted,
not in the way you claim.
How long have you been programming with MS solutions not to know that
what happens in development or the test environments may not hold true
when a solution hit's out there in the production environment?
Actually, I've been programming with MS solutions long enough to know that
they work a lot better than some people would like us to believe. And
that other solutions aren't nearly as superior as those same people would
like us to believe.

But even so, let's assume that .NET is riddled with bugs and there's a
possibility in the loop that was posted that "you're going to eventually
blow up at that RemoveAt(i)". If that's true (and I don't believe it is),
then it has absolutely zero to do with how the variable "i" is
decremented. The loop could be completely rewritten (in the way that I
suggested, for example), without the extra decrement, and the statement
"you're going to eventually blow up at that RemoveAt(i)" would be just as
true as it was with the original code.
You ever had to go out to a production server and debug code that worked
perfectly in development and test environments but not in production?
I've had plenty of situations in which bugs were not found in production,
due to user scenarios that had not been anticipated and/or tested, as well
as a very small number of situations in which bugs in third-party code was
causing a problem with my own code.

But, so what? None of that changes the fact that any presumed problem you
might care to point out has ZERO to do with whether the code decrements
the variable "i" or not.

Pete

May 15 '07 #24

P: n/a

"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Mon, 14 May 2007 20:06:54 -0700, Mr. Arnold <MR. <Ar****@Arnold.com>>
wrote:
>This is beyond the whole little loop function. I am surprised that you
don't understand the statement above that I made.

You wrote:

"No, you don't decrement (i) like that, you're going to eventually blow up
at that RemoveAt(i)"
>
That statement is simply false. But, if you're going to assert that it is
true because .NET is buggy, then the conclusion ("you're going to
eventually blow up") has nothing at all to do with the exposition ("you
don't decrement (i) like that").
This is all coming from you. I didn't say anything about .NET being buggy.
It's out of your mouth that it's being said.

All I said was not to decrement (i) like that, that the loop is controlling,
which could possibly lead to a termination at RemoveAt(i).

Normally, one does't decrement (i) like that in a loop. Normally, one lets
the loop increment or decrement the count itself. Now, one could do an j=i-1
or j=i+1 and work with j, but one doesn't mess with (i). That's kind of
common sense.

One could just look a tlist.count and with j determine that it's time to
leave the loop.
>
Either way, there is nothing wrong at all with the code that was posted,
not in the way you claim.
Again, I never said there was nothing wrong with the code. This is coming
out of your mouth, not mine.
>
>How long have you been programming with MS solutions not to know that
what happens in development or the test environments may not hold true
when a solution hit's out there in the production environment?

Actually, I've been programming with MS solutions long enough to know that
they work a lot better than some people would like us to believe. And
that other solutions aren't nearly as superior as those same people would
like us to believe.
Well, you can't come up with number of months or years, then that tells me
not long at all.

I have been programming MS solutions, since 1994. I been programming
business solutions since 1980. I have been in the IT field since 1971 and
still going strong.
>
But even so, let's assume that .NET is riddled with bugs and there's a
possibility in the loop that was posted that "you're going to eventually
blow up at that RemoveAt(i)". If that's true (and I don't believe it is),
then it has absolutely zero to do with how the variable "i" is
decremented.
Will you get off of the loop, you have beaten the loop into the ground.
>The loop could be completely rewritten (in the way that I suggested, for
example),
LOL as you have suggested. Who are you?
without the extra decrement, and the statement "you're going to
eventually blow up at that RemoveAt(i)" would be just as true as it was
with the original code.
I didn't see your suggestion nor do I care to see it either.
>
>You ever had to go out to a production server and debug code that worked
perfectly in development and test environments but not in production?

I've had plenty of situations in which bugs were not found in production,
due to user scenarios that had not been anticipated and/or tested, as well
as a very small number of situations in which bugs in third-party code was
causing a problem with my own code.
I am not even talking about some user scenarios that had not been
anticipated. It's more along the lines of Com and Com+ solutions being used
in a enterprise solution.
which things didn't work as aspected, with the same code working without
Com+, as an example.
>
But, so what? None of that changes the fact that any presumed problem you
might care to point out has ZERO to do with whether the code decrements
the variable "i" or not.
You are one of these people that has a corn cob stuck up your behind, you
know it all, you got to prove it and you got a mental problem.

I have seen your kind before off the job and on the job as well.

Here comes Pete he's a PITA. Let's cut him off and leave before he gets
started.

May 15 '07 #25

P: n/a
<"Mr. Arnold" <MR. Ar****@Arnold.com>wrote:
That statement is simply false. But, if you're going to assert that it is
true because .NET is buggy, then the conclusion ("you're going to
eventually blow up") has nothing at all to do with the exposition ("you
don't decrement (i) like that").

This is all coming from you. I didn't say anything about .NET being buggy.
It's out of your mouth that it's being said.
Excuse me? How about:

<quote>
Don't you know? It's MS and what works up in the IDE and what works
when you deploy it are two different things. I have been there an done
that. :)
</quote>

and

<quote>
How long have you been programming with MS solutions not to know that
what happens in development or the test environments may not hold true
when a solution hit's out there in the production environment?
</quote>

To me that sounds like a suggestion that you believe it's buggy.
Perhaps you could correct my interpretation of your posts.

<snip>
You are one of these people that has a corn cob stuck up your behind, you
know it all, you got to prove it and you got a mental problem.
Funny how different people come to different conclusions. I've been
reaching the conclusion that Peter is one of the most experienced
posters (not necessarily in C#, but that's a different matter - and one
which is rapidly changing) in the group. When we disagree, it always
leads to a productive discussion which informs both of us.

I for one would welcome more posters of his calibre.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 15 '07 #26

P: n/a

"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP********************@msnews.microsoft.com.. .
<"Mr. Arnold" <MR. Ar****@Arnold.com>wrote:
That statement is simply false. But, if you're going to assert that it
is
true because .NET is buggy, then the conclusion ("you're going to
eventually blow up") has nothing at all to do with the exposition ("you
don't decrement (i) like that").

This is all coming from you. I didn't say anything about .NET being
buggy.
It's out of your mouth that it's being said.

Excuse me? How about:

<quote>
Don't you know? It's MS and what works up in the IDE and what works
when you deploy it are two different things. I have been there an done
that. :)
</quote>

and

<quote>
How long have you been programming with MS solutions not to know that
what happens in development or the test environments may not hold true
when a solution hit's out there in the production environment?
</quote>

To me that sounds like a suggestion that you believe it's buggy.
Perhaps you could correct my interpretation of your posts.
MS solutions as far back Visual Basic 3.0 that I have worked with have had
issues, some little quirkiness in them.

It's been my experience that some things just don't work as expected with MS
solutions, sometimes, and one has to be aware of it. Not just with MS
solutions, but with all the solutions on various platforms I have worked on
over the years have had quirkiness about them.

After all, it's all written by fallible Human Beings. When we are prefect,
then I'll expect everything we do or create to be perfect. Well, that's not
the case with anything we create or do.

And there were IDE(s) for MS solutions well before .NET hit the scene.

Now, you can interpret that anyway you want. But that does not indicate that
I was speaking of .Net's IDE per say, but rather, what my experiences have
been in programming MS solutions over the years.
>
<snip>
>You are one of these people that has a corn cob stuck up your behind, you
know it all, you got to prove it and you got a mental problem.

Funny how different people come to different conclusions. I've been
reaching the conclusion that Peter is one of the most experienced
posters (not necessarily in C#, but that's a different matter - and one
which is rapidly changing) in the group. When we disagree, it always
leads to a productive discussion which informs both of us.

I for one would welcome more posters of his calibre.
I am happy that you feel that way about him. I'll put it to you point blank.
He doesn't mean anything to me. I think he is a PITA with a smart mouth,
from my encounter with him.

The whole thing is/was much to do about *nothing*, and I'll know to avoid
him in the future.

May 15 '07 #27

P: n/a
Well, you have to admire frankness; it saves a lot of time.

I have just re-read all of Peter's posts in this chain, and all of
them seem perfectly contextual, factual (not personal / judgemental),
polite, businesslike and proper.

Without tone-of-voice, can I humbly suggest that you might have taken
some comment(s) in a way that the rest of us just aren't seeing?
Anyway, it doesn't matter much in the grand scheme; let's just get
along, eh?

Marc
May 15 '07 #28

P: n/a

"Marc Gravell" <ma**********@gmail.comwrote in message
news:eL**************@TK2MSFTNGP04.phx.gbl...
Well, you have to admire frankness; it saves a lot of time.

I have just re-read all of Peter's posts in this chain, and all of them
seem perfectly contextual, factual (not personal / judgemental), polite,
businesslike and proper.

Without tone-of-voice, can I humbly suggest that you might have taken some
comment(s) in a way that the rest of us just aren't seeing? Anyway, it
doesn't matter much in the grand scheme; let's just get along, eh?
I'll just say this. I didn't read all of his posts. The last post he posted
to me, I considered parts of it to be out line, showing disrepect.

We'll leave it at that and move on. I suspect I'll just have to ignore him.

May 15 '07 #29

P: n/a
You wrote:
>
"No, you don't decrement (i) like that, you're going to eventually blow up
at that RemoveAt(i)"

That statement is simply false.
Exactly. It's funny how the current argument has absolutely nothing
to do with the initial claim. The initial claim is simply wrong.

Mr. Arnold, you claim that my original code was wrong is simply
false. If you're trying to make a statement other than this, then you
need to be very clear about what you are talking about, and you should
clear up what you meant to say instead of the above. I have come to
the same conclusions as to what you're trying to get at as Peter has,
and your reaction is that he's putting words in your mouth. But, no
one is reading your mind, so all we can go by is your words, and
that's how we are dervied what your argument is. Right now, you're
doing a poor job of explaining what exactly is wrong with my (ugly)
code, so we're struggling to understand where you're coming from,
especially when the code is 100% legitimate and will never blow up.

The only thing I can get from you is that it's Bad News to mess with
the loop iterator within the loop. But, the way loops are implemented
are well defined, so this is ok.

I am completely lost with your position.

Zytan

May 15 '07 #30

P: n/a
I'll put it to you point blank.
He doesn't mean anything to me. I think he is a PITA with a smart mouth,
from my encounter with him.
That type of reaction only arrives from being defensive. It's
illogical, and emotional, and thus meaningless. Once you step back
from this argument, and remove the emotional, you will certainly agree
that your above conclusion is false. Wht? Because I am uncertain how
he could have possibly been more factual and logical in his words. I
can't say the same for you, because nothing you've said was clear
(actually, it was clear, but then you say you meant something else, so
it become very unclear, and totally lost me).
The whole thing is/was much to do about *nothing*, and I'll know to avoid
him in the future.
Actually, it was about you saying that changing the loop iterator
within a loop is bound to blow up. Peter tried to tell you this is
completely false. He's right.

Arnold, I seriously appreciate your effort to show me that my code was
wrong, but I still have no idea why you think it is wrong. Just tell
me what is wrong with it. Because NET may change the way loops are
implemented? Perhaps an optimization could affect the way an
interator is changed in mid-loop? I agree it seems ugly. Back in the
day they used to be optimized to the CX register, and changing it in
mid-stream would have no effect. It still seems ugly to do it today
(I've never argued my code was nice), but I believe that the loop
implementation allows this now, and that's not going to change, for
backwards compatibility reasons if nothing else.

Zytan

May 15 '07 #31

P: n/a
On Mon, 14 May 2007 23:06:48 -0700, Mr. Arnold <MR. <Ar****@Arnold.com>>
wrote:
This is all coming from you. I didn't say anything about .NET being
buggy. It's out of your mouth that it's being said.
All of your posts have defended the claim that the loop will "blow up"
based on the assertion that "MS solutions" don't do what they're supposed
to. I'm not sure how I'm supposed to interpret that other than you
claiming .NET is buggy.
All I said was not to decrement (i) like that, that the loop is
controlling, which could possibly lead to a termination at RemoveAt(i)..
The only way decrementing the variable i "could possibly lead to a
termination at RemoveAt(i)" is if .NET is buggy. The language is
well-defined and the behavior of the loop is well-defined based on the
language, and according to the language definition, the loop has no
trouble at all with decrementing the variable i in the loop. So, again,
the only way anything wrong could happen is if .NET doesn't implement the
language correctly.

In other words, it's buggy.
Normally, one does't decrement (i) like that in a loop. Normally, one
lets the loop increment or decrement the count itself. Now, one could do
an j=i-1 or j=i+1 and work with j, but one doesn't mess with (i). That's
kind of common sense.
I beg to differ. I agree that it's generally poor convention to modify a
loop counter from within the loop, but both C and C#, and any number of
other languages, do permit it and the behavior is well-defined.
[...]
>Either way, there is nothing wrong at all with the code that was
posted, not in the way you claim.

Again, I never said there was nothing wrong with the code. This is
coming out of your mouth, not mine.
You said it would "blow up". How is that not saying that there's
something wrong with the code?
[...]
Well, you can't come up with number of months or years, then that tells
me not long at all.

I have been programming MS solutions, since 1994. I been programming
business solutions since 1980. I have been in the IT field since 1971
and still going strong.
lol...I didn't realize this was a pissing contest. Sorry. I admit, I
haven't been "in the IT field since 1971", but I have a lot more
experience than you are giving me credit for (and more experience with
Microsoft and Windows than you yourself have). In any case, this
discussion isn't about who has the most experience. If I had only been
writing Windows software for 12 months, my statements would be just as
correct as they are given the experience I do have.
Will you get off of the loop, you have beaten the loop into the ground..
Why would I comment on anything *but* the loop? This entire thread is
about the loop.
[...]
>without the extra decrement, and the statement "you're going to
eventually blow up at that RemoveAt(i)" would be just as true as it
was with the original code.

I didn't see your suggestion nor do I care to see it either.
I suppose that's your prerogative. I was simply using my other post
elsewhere in this thread as an informative example. If you don't care to
consider all of the available information, you are free to choose not to..
[...]
I am not even talking about some user scenarios that had not been
anticipated. It's more along the lines of Com and Com+ solutions being
used in a enterprise solution.
which things didn't work as aspected, with the same code working without
Com+, as an example.
In what way is that relevant to whether one should modify a loop counter
from within the loop?
You are one of these people that has a corn cob stuck up your behind,
you know it all, you got to prove it and you got a mental problem.
It's true, I have an almost pathological need to get the details right.
Turns out that's actually a useful personality trait in the programming
business. Still, my pathological need to get the details right doesn't
change the incorrectness of claiming that there's something fundamentally
wrong with modifying the loop index from within the loop.

As near as I can tell, the main reason my pathological need to get the
details right annoys you so much is that you yourself have the details
wrong, and pointing that out bothers you for some reason.

For what it's worth, I've made my own share of mistakes posting in this
newsgroup (and others, for that matter). People have pointed those
mistakes out, and rather than getting all defensive about it, I simply
admit my mistake and move on. You might consider that approach as being
more useful and productive in your own posts.

Nobody is perfect, and nobody should expect anyone else to be perfect.
The real question is whether a person has enough character to admit their
mistake and learn from it, rather than dig in their heels and create a
mountain out of a molehill.

Pete
May 15 '07 #32

P: n/a
<Plank- That's a soft logical <plonk>.

I didn't bother to read it.

It's time for you to <disappear>.
May 15 '07 #33

P: n/a
<snipped>
I am completely lost with your position.
I see it differently, and somehow you got it into your head that what I told
you what you were doing was wrong. I don't recall me writing the word
*wrong* in any sentence.

If you go back to my posts to you or to this other person Pete, you pick the
one sentence where I wrote the word *wrong*.

All I said is that you shouldn't use (i) the way you were doing it, because
that could lead to the loop blowing.

In the long run, you do what you want. It's your code. You have to support
it, not me.

I really don't care. It's much to do about nothing with you and the *loop*.

May 15 '07 #34

P: n/a
On Tue, 15 May 2007 11:01:55 -0700, Mr. Arnold <MR. <Ar****@Arnold.com>>
wrote:
[...]
All I said is that you shouldn't use (i) the way you were doing it,
because that could lead to the loop blowing.
But that's not a true statement. Using "i" the way he's using it could
*not* "lead to the loop blowing".

(Ignoring for the moment the odd implication of your post that saying that
the loop could "blow" is not the same as saying that it's "wrong")
May 15 '07 #35

P: n/a
<"Mr. Arnold" <MR. Ar****@Arnold.com>wrote:
I am completely lost with your position.

I see it differently, and somehow you got it into your head that what I told
you what you were doing was wrong. I don't recall me writing the word
*wrong* in any sentence.
You don't need to write the word "wrong" in order to give the
impression that what someone is doing is wrong. For instance:

<quote>
All I said was not to decrement (i) like that, that the loop is
controlling, which could possibly lead to a termination at RemoveAt(i).
</quote>

Telling someone not to do something gives the impression that you think
that what they're doing is wrong, doesn't it?

Likewise:

<quote>
No, you don't decrement (i) like that, you're going to eventually blow
up at that RemoveAt(i).
</quote>

Saying that someone's code will "eventually blow up" is telling them
that their code is wrong, in my opinion.
Just as another example of this, but this time from me, just now:

Saying that the loop will blow up is an incorrect statement.

There - I've just said that you were wrong, without using the word
"wrong" in the sentence at all, haven't I?
If you go back to my posts to you or to this other person Pete, you pick the
one sentence where I wrote the word *wrong*.
That's easy:

<quote>
Again, I never said there was nothing wrong with the code.
</quote>

Message-ID: <#u**************@TK2MSFTNGP06.phx.gbl>

The double negative doesn't help matters, but it certainly includes the
word "wrong".
All I said is that you shouldn't use (i) the way you were doing it, because
that could lead to the loop blowing.
Except that it couldn't, which is Pete's point. The code *won't* blow
up, unless there really *is* a bug in .NET in this respect, which
(despite your later claims to the contrary) you heavily implied that
there is.

That doesn't mean the code is the best way of writing it - no-one ever
claimed it is. We've just all maintained that it won't "blow up" at
mylist.Remove(i) contrary to your claim.

Now, were you actually maintaining that you believe there *is* a bug in
..NET (in which case you should apologise to Peter for saying "This is
all coming from you. I didn't say anything about .NET being buggy.
It's out of your mouth that it's being said") or were you maintaining
that the code did actually have something wrong with it, a logical
error which can cause it to fail *without* there being a bug in .NET
(in which case you should show that error)?
I really don't care. It's much to do about nothing with you and the *loop*.
The trouble is that by repeatedly claiming that the loop won't work
without giving any evidence, and by making ad hominem attacks, you've
made it about more than the loop. You've made it about an inability to
back down.

I wouldn't have got involved in this thread at all if you hadn't
started attacking Peter without any cause, for example.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 15 '07 #36

P: n/a
Please, you're painful.
May 15 '07 #37

P: n/a
Please, you're painful.
May 15 '07 #38

P: n/a
Please, you are just illustrating how really stupid you are.
On 16/5/07 5:06 AM, in article OH**************@TK2MSFTNGP04.phx.gbl, "Mr.
Arnold" <MR. Ar****@Arnold.comwrote:
Please, you're painful.
May 15 '07 #39

P: n/a
Yeah, yeah now <disappearyou have said what you needed to say, move on.
May 15 '07 #40

P: n/a
......somehow you got it into your head that
what I told you what you were doing was wrong.
I have no idea why.
All I said is that you shouldn't use (i) the way you were
doing it, because that could lead to the loop blowing.
Oh, that's why.

Zytan

May 15 '07 #41

P: n/a

"Zytan" <zy**********@gmail.comwrote in message
news:11**********************@q75g2000hsh.googlegr oups.com...
>......somehow you got it into your head that
what I told you what you were doing was wrong.

I have no idea why.
>All I said is that you shouldn't use (i) the way you were
doing it, because that could lead to the loop blowing.

Oh, that's why.
Please, let's forget about your little loop example. Let's just take dealing
with the idx counter on the loop, period.

Under normal circumstances, one doesn't mess with the count idx. It's a best
programming practice that's used by many.

Most use another variable an indirect method to control the loop, if they
need a way of terminating out of the loop based on the iteration count.

So your way works, big deal. Your way would simply not be the way I would do
it. I would never let your way come through a code review if you were
setting in front of me.

It's a bad habit a lazy habit of programming, that could lead to trouble in
the long run in other areas where you worked a project.

I would never directly start controlling the idx counter of a loop. the way
you're doing it.

By an indirect method of controlling the count to control the loop, yes.

Your way should never hit the light of day IMHO. Is it wrong, no it's not
wrong. Is it a best practice, no it's not a best practice either.

That's just the way I was taught.

This will be my last post on this subject, because I am through with you and
anybody else that needs to make a comment. There will not be a return reply.
It won't be read by me, because I am moving on.



May 15 '07 #42

P: n/a
On Tue, 15 May 2007 15:42:52 -0700, Mr. Arnold <MR. <Ar****@Arnold.com>>
wrote:
[...]
Under normal circumstances, one doesn't mess with the count idx. It's a
best programming practice that's used by many.
That's true...it's generally bad form to modify a for() loop index outside
the for() statement. No one's disagreed with that.
Most use another variable an indirect method to control the loop, if
they need a way of terminating out of the loop based on the iteration
count.
Well, it is fairly common to use a different looping construct, such as
"while() { }" or "do { } while ()", when one intends for the looping
condition to be adjusting in non-linear ways inside the loop. It's not
that one doesn't modify a loop control variable from within the loop, it's
just that one doesn't normally do it with a for() loop.
So your way works, big deal. Your way would simply not be the way I
would do it. I would never let your way come through a code review if
you were setting in front of me.
That's fine. If you are in the position to impose your own requirements
on someone else's code, you're free to come up with whatever rules you
like. And in fact, I would probably strongly urge someone to change the
loop if I saw the same thing.

Still, no one's disagreed with the concern that the loop is poorly
formed. So your assertion here is not relevant.
It's a bad habit a lazy habit of programming, that could lead to trouble
in the long run in other areas where you worked a project.
Again, no one disagreed with this.
I would never directly start controlling the idx counter of a loop. the
way you're doing it.
Again, no one disagreed with this.
By an indirect method of controlling the count to control the loop, yes.

Your way should never hit the light of day IMHO. Is it wrong, no it's
not wrong. Is it a best practice, no it's not a best practice either.

That's just the way I was taught.
All of the above, no one has disagreed with. All of those assertions are
preaching to the choir and irrelevant to your original claim.

So why did you leave out your original claim, that the loop would blow
up? Is it possible that you've seen the error of your ways and realized
that the loop will not in fact blow up? Why not just admit it?
This will be my last post on this subject, because I am through with you
and anybody else that needs to make a comment. There will not be a
return reply. It won't be read by me, because I am moving on.
Cool. I love getting the last word. Another one of those pesky
personality defects I've got. :)

Pete
May 15 '07 #43

P: n/a

"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Tue, 15 May 2007 15:42:52 -0700, Mr. Arnold <MR. <Ar****@Arnold.com>>
wrote:
>[...]
Under normal circumstances, one doesn't mess with the count idx. It's a
best programming practice that's used by many.

That's true...it's generally bad form to modify a for() loop index outside
the for() statement. No one's disagreed with that.
>Most use another variable an indirect method to control the loop, if
they need a way of terminating out of the loop based on the iteration
count.

Well, it is fairly common to use a different looping construct, such as
"while() { }" or "do { } while ()", when one intends for the looping
condition to be adjusting in non-linear ways inside the loop. It's not
that one doesn't modify a loop control variable from within the loop, it's
just that one doesn't normally do it with a for() loop.
>So your way works, big deal. Your way would simply not be the way I
would do it. I would never let your way come through a code review if
you were setting in front of me.

That's fine. If you are in the position to impose your own requirements
on someone else's code, you're free to come up with whatever rules you
like. And in fact, I would probably strongly urge someone to change the
loop if I saw the same thing.

Still, no one's disagreed with the concern that the loop is poorly
formed. So your assertion here is not relevant.
>It's a bad habit a lazy habit of programming, that could lead to trouble
in the long run in other areas where you worked a project.

Again, no one disagreed with this.
>I would never directly start controlling the idx counter of a loop. the
way you're doing it.

Again, no one disagreed with this.
>By an indirect method of controlling the count to control the loop, yes.

Your way should never hit the light of day IMHO. Is it wrong, no it's
not wrong. Is it a best practice, no it's not a best practice either.

That's just the way I was taught.

All of the above, no one has disagreed with. All of those assertions are
preaching to the choir and irrelevant to your original claim.

So why did you leave out your original claim, that the loop would blow
up? Is it possible that you've seen the error of your ways and realized
that the loop will not in fact blow up? Why not just admit it?
>This will be my last post on this subject, because I am through with you
and anybody else that needs to make a comment. There will not be a
return reply. It won't be read by me, because I am moving on.

Cool. I love getting the last word. Another one of those pesky
personality defects I've got. :)

Pete
May 15 '07 #44

P: n/a

Cool. I love getting the last word. Another one of those pesky
personality defects I've got. :)
Is the boy's code going to blow, no. Is his method of messing with the idx
going to possibly cause trouble from him in the long run with a lazy
programming practice, which was my point in the first place? Most likely,
yes, it's going to be that way for him. Is the code a piece of trash. Yes,
it is a piece of trash.

So, the bottom line is it's a "D-" and it's barely above *wrong* from my
view point.

It's just my parting *shot*.

May 15 '07 #45

P: n/a
Zytan,

As it makes me uncomfortable to evaluate an object's property during each
iteration of a loop, here's how I like to clear lists:

List<typemyList = .... something ;
for (int i=myList.Count - 1; i >= 0; i--)
{
myList.RemoveAt(i);
}

Jon

"Zytan" <zy**********@gmail.comwrote in message
news:11**********************@u30g2000hsc.googlegr oups.com...
Obviously you can't just use a simple for loop, since you may skip
over elements.

You could modify the loop counter each time an element is deleted.
But, the loop ending condition must be checked on each iteration,
since the Count changes as you delete elements. I would think it is
guaranteed to be computed each time, and not cached.

So, is this the best way?

List<intmylist = .......something......;
for (int i=0; i<mylist.Count; i++) {
if (want_to_remove) {
mylist.RemoveAt(i);
i--;
}
}

Zytan
May 16 '07 #46

P: n/a
... more to the point ..

for (int i=myList.Count - 1; i >= 0; i--)
{
if (ShouldBeDiscarded(myList[i]))
{
myList.RemoveAt(i);
}
}

Note that this in itself isn't thread-safe. The point of it is that, using
this approach, removing an item at i doesn't suddenly invalidate the
consecutive items to be evaluated, unless your list is not a standard list
and is using some kind of dynamic re-sorting.

Jon

"Jon Davis" <jo*@REMOVE.ME.PLEASE.jondavis.netwrote in message
news:er**************@TK2MSFTNGP05.phx.gbl...
Zytan,

As it makes me uncomfortable to evaluate an object's property during each
iteration of a loop, here's how I like to clear lists:

List<typemyList = .... something ;
for (int i=myList.Count - 1; i >= 0; i--)
{
myList.RemoveAt(i);
}

Jon

"Zytan" <zy**********@gmail.comwrote in message
news:11**********************@u30g2000hsc.googlegr oups.com...
>Obviously you can't just use a simple for loop, since you may skip
over elements.

You could modify the loop counter each time an element is deleted.
But, the loop ending condition must be checked on each iteration,
since the Count changes as you delete elements. I would think it is
guaranteed to be computed each time, and not cached.

So, is this the best way?

List<intmylist = .......something......;
for (int i=0; i<mylist.Count; i++) {
if (want_to_remove) {
mylist.RemoveAt(i);
i--;
}
}

Zytan
May 16 '07 #47

P: n/a
Jon Davis <jo*@REMOVE.ME.PLEASE.jondavis.netwrote:
As it makes me uncomfortable to evaluate an object's property during each
iteration of a loop, here's how I like to clear lists:
Why does it make you uncomfortable? For performance reasons? I'd rather
take the simplicity and familiarity of a "counting up" loop (without
having to remember to use >= instead of and Count-1 as the starting
point) and only adjust this for the sake of performance if it actually
comes up.

In fact, there's a more important performance reason (which I still
wouldn't care about until you prove you have an issue) - removing from
the end reduces the copying that needs to be done. Imagine the
situation where *every* element is removed - with the "counting down"
code, no copying is required; by counting up you've got to copy the
whole remaining list each time.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 16 '07 #48

P: n/a
On Tue, 15 May 2007 16:48:51 -0700, Mr. Arnold <MR. <Ar****@Arnold.com>>
wrote:
Is the boy's code going to blow, no.
Now, see? Was that really so hard? To finally admit you were wrong in
the first place? No, of course not! :)

It's wonderful that you finally saw the light and I hope that admitting
your mistake helps make you feel better.

Pete
May 16 '07 #49

P: n/a
There was no light to see.

<Plankthat's a soft logical <plonk>.
May 16 '07 #50

56 Replies

This discussion thread is closed

Replies have been disabled for this discussion.