|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
RemoveAt in foreach { ... }Is there any efficient way doing Dictionary<>.RemoveAt in foreach { ... }
routine? For example, is this example safe or is there any recommended way? foreach(KeyValuePair<int,int> a in mymap) { if(a.Value!=GoodValue) { mymap.RemoveAt(a.Key); // and continues the iteration } } Please reply. Thanks in advance. Hyun-jik Bae
Show quote
"Hyun-jik Bae" <imays_NOSPAM_@paran.com> wrote in message I don't remember exactly but I was reading something about this the other news:OkzUTm27GHA.4572@TK2MSFTNGP02.phx.gbl... > Is there any efficient way doing Dictionary<>.RemoveAt in foreach { ... } > routine? > For example, is this example safe or is there any recommended way? > > foreach(KeyValuePair<int,int> a in mymap) > { > if(a.Value!=GoodValue) > { > mymap.RemoveAt(a.Key); // and continues the iteration > } > } > day and I believe its not safe but there is a good way to fix it. I'm not sure if it involes working on a temp copy or not though. i.e., you could easily get around it by creating a shallow copy of mymap and then working on that temp in the inner loop. Sorry but thats the best I could do(I though I'd mention it just incase you don't get to many replies). Jon You can't change the collection that you are looping through. Changing
the collection makes the enumerator invalid, and it will throw an exception when you try to continue the loop. One way to do it is to add the keys that you want to remove to a list, then when you have looped through the dictionary, you loop throught the list to remove the items from the dictionary. Hyun-jik Bae wrote: Show quote > Is there any efficient way doing Dictionary<>.RemoveAt in foreach { ... } > routine? > For example, is this example safe or is there any recommended way? > > foreach(KeyValuePair<int,int> a in mymap) > { > if(a.Value!=GoodValue) > { > mymap.RemoveAt(a.Key); // and continues the iteration > } > } > > Please reply. Thanks in advance. > > Hyun-jik Bae Hyun-jik Bae,
Which collection are you using? Dictionary does not have a RemoveAt method. As others have said removing an item will invalidate the enumerator. It's better to figure out what you want to remove in one loop and then actually remove in another. Brian Hyun-jik Bae wrote: Show quote > Is there any efficient way doing Dictionary<>.RemoveAt in foreach { ... } > routine? > For example, is this example safe or is there any recommended way? > > foreach(KeyValuePair<int,int> a in mymap) > { > if(a.Value!=GoodValue) > { > mymap.RemoveAt(a.Key); // and continues the iteration > } > } > > Please reply. Thanks in advance. > > Hyun-jik Bae Brian Gideon wrote:
> Which collection are you using? Dictionary does not have a RemoveAt As he was feeding the key into the method, I assume that he means the > method. Remove method, that takes a key as argument. A RemoveAt method would take an index instead of a key. Show quote :) Sorry, that's my mistake. I should have shown Remove(), not RemoveAt().
Hyun-jik Bae Show quote "Brian Gideon" <briangid***@yahoo.com> wrote in message news:1160845635.093200.277890@h48g2000cwc.googlegroups.com... > Hyun-jik Bae, > > Which collection are you using? Dictionary does not have a RemoveAt > method. > > As others have said removing an item will invalidate the enumerator. > It's better to figure out what you want to remove in one loop and then > actually remove in another. > > Brian > > Hyun-jik Bae wrote: >> Is there any efficient way doing Dictionary<>.RemoveAt in foreach { >> ... } >> routine? >> For example, is this example safe or is there any recommended way? >> >> foreach(KeyValuePair<int,int> a in mymap) >> { >> if(a.Value!=GoodValue) >> { >> mymap.RemoveAt(a.Key); // and continues the iteration >> } >> } >> >> Please reply. Thanks in advance. >> >> Hyun-jik Bae > Hyun-jik Bae,
No need to be sorry. I was just wanting clarification. Obviously, all of the responses regarding RemoveAt are irrelevant now. I think your best option is to use the two loop method; one to figure out what you want to remove and the other to actually remove them. Brian Hyun-jik Bae wrote: Show quote > Sorry, that's my mistake. I should have shown Remove(), not RemoveAt(). > > Hyun-jik Bae > Hyun-jik,
Although that there are possibilities, I never will use RemoveAt in a foreach loop. I will alway use to RemoveAt a For index with a bottom up loop. Cor Show quote "Hyun-jik Bae" <imays_NOSPAM_@paran.com> schreef in bericht news:OkzUTm27GHA.4572@TK2MSFTNGP02.phx.gbl... > Is there any efficient way doing Dictionary<>.RemoveAt in foreach { ... } > routine? > For example, is this example safe or is there any recommended way? > > foreach(KeyValuePair<int,int> a in mymap) > { > if(a.Value!=GoodValue) > { > mymap.RemoveAt(a.Key); // and continues the iteration > } > } > > Please reply. Thanks in advance. > > Hyun-jik Bae > > Although that there are possibilities, I never will use RemoveAt in a I don't think there are any possibilities.> foreach loop. The enumerator would immediately become invalid.... Correct way: 1. Iterate through all entries. 2. Grab all those required in another list. 3. Remove all these "collected" (grabbed) entries from the original list/collection. The only way. -- Happy Hacking, Gaurav Vaish | www.mastergaurav.com www.edujinionline.com http://eduzine.edujinionline.com ----------------------------------------- > No bottom up is easier,> Correct way: > > 1. Iterate through all entries. > 2. Grab all those required in another list. > 3. Remove all these "collected" (grabbed) entries from the original > list/collection. > > The only way. > For (int i = mycollection.count - 1;i > -1;i--) { if (whatever) removeAt(i);} Cor or
while (dict.Count > 0) dict.RemoveAt(0); -- Show quoteMilosz Skalecki MCP, MCAD "Cor Ligthert [MVP]" wrote: > > > > Correct way: > > > > 1. Iterate through all entries. > > 2. Grab all those required in another list. > > 3. Remove all these "collected" (grabbed) entries from the original > > list/collection. > > > > The only way. > > > No bottom up is easier, > > For (int i = mycollection.count - 1;i > -1;i--) > { if (whatever) removeAt(i);} > > Cor > > > > Milosz Skalecki <mily***@REMOVEITwp.pl> wrote:
> or That only works if you're trying to clear the whole thing though - in > while (dict.Count > 0) > dict.RemoveAt(0); which case there are usually much simpler ways of doing it. -- 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 "Cor Ligthert [MVP]" <notmyfirstn***@planet.nl> wrote in message Just to be ornery, I'll point out that I like top down better:news:u7kiAQ97GHA.608@TK2MSFTNGP03.phx.gbl... > No bottom up is easier, > > For (int i = mycollection.count - 1;i > -1;i--) > { if (whatever) removeAt(i);} int i = 0 while (i < mycollection.Count) { if (!whatever) { i++; continue; } mycollection.RemoveAt(i); } :) (I actually do like that better, because the code is IMHO more readable; too many "minuses" and "offsets by one" in the bottom up version for my tastes) Pete The top down approach has another major benefit - it doesn't invalidate the
indexes of elements you haven't examed yet for removal. Mike Ober. Show quote "Peter Duniho" <NpOeStPe***@NnOwSlPiAnMk.com> wrote in message news:12j3m036h8fv8ff@corp.supernews.com... > "Cor Ligthert [MVP]" <notmyfirstn***@planet.nl> wrote in message > news:u7kiAQ97GHA.608@TK2MSFTNGP03.phx.gbl... > > No bottom up is easier, > > > > For (int i = mycollection.count - 1;i > -1;i--) > > { if (whatever) removeAt(i);} > > Just to be ornery, I'll point out that I like top down better: > > int i = 0 > while (i < mycollection.Count) > { > if (!whatever) > { > i++; > continue; > } > mycollection.RemoveAt(i); > } > > > :) > > (I actually do like that better, because the code is IMHO more readable; too > many "minuses" and "offsets by one" in the bottom up version for my tastes) > > Pete > > > Michael,
Feel free to use even 100 loops if you want. I think that one short loop bottom up through the index is never to beat. Probably nobody has tested it but are just telling that their long time taking approaches are the best. This method is however not from me. Armin Zingler came with it I thought about 3 years ago in the Visual Basic newsgroup, where all what is showed now in this newsgroup was showed before that. Now nobody active in the Visual Basic newsgroup will think on other than bottom up methods for these problems, while they did before this top down, with all those work around methods showed here. Cor Show quote "Michael D. Ober" <ober***@.alum.mit.edu.nospam> schreef in bericht news:mkxYg.14242$UG4.9725@newsread2.news.pas.earthlink.net... > The top down approach has another major benefit - it doesn't invalidate > the > indexes of elements you haven't examed yet for removal. > > Mike Ober. > > "Peter Duniho" <NpOeStPe***@NnOwSlPiAnMk.com> wrote in message > news:12j3m036h8fv8ff@corp.supernews.com... >> "Cor Ligthert [MVP]" <notmyfirstn***@planet.nl> wrote in message >> news:u7kiAQ97GHA.608@TK2MSFTNGP03.phx.gbl... >> > No bottom up is easier, >> > >> > For (int i = mycollection.count - 1;i > -1;i--) >> > { if (whatever) removeAt(i);} >> >> Just to be ornery, I'll point out that I like top down better: >> >> int i = 0 >> while (i < mycollection.Count) >> { >> if (!whatever) >> { >> i++; >> continue; >> } >> mycollection.RemoveAt(i); >> } >> >> >> :) >> >> (I actually do like that better, because the code is IMHO more readable; > too >> many "minuses" and "offsets by one" in the bottom up version for my > tastes) >> >> Pete >> >> >> > > > "Cor Ligthert [MVP]" <notmyfirstn***@planet.nl> wrote in message "Never to beat"? In what respect? In programming, there are far too many news:uExxO2N8GHA.4224@TK2MSFTNGP02.phx.gbl... > Feel free to use even 100 loops if you want. I think that one short loop > bottom up through the index is never to beat. competing goals for anyone to say one solution is the best one 100% of the time. I think it unlikely that if you are iterating through an entire indexed collection and removing some subset of that collection, you'll see a significant difference between various means of iteration, in the most common cases. If you're dealing with an array, and each removal requires that the remaining elements in the array be copied down, then yes...starting at the end will result in a slightly better performance. However, unless you're deleting most of the members of the array, you won't notice this difference. The total data moved will only be a little less that way, and it ignores the benefit of code clarity. If performance is an issue, then the right way is to simply copy the references to be preserved to a new array, and then just delete the entire original. This method will perform WAY better than either a top-down or bottom-up in-place removal. If performance is not an issue, then you can't use performance as the sole measure of which method is better. If you're dealing with a linked list, then removal by index is going to perform poorly whichever end you start at, and there will be better performance starting at the beginning (top-down) than the end (bottom-up). A better way than using an index from either end would be to iterate through the list by reference, so that removal operations have constant order. > [...] I hate to tell you this, but the question of removing elements from an > This method is however not from me. Armin Zingler came with it I thought > about 3 years ago in the Visual Basic newsgroup, where all what is showed > now in this newsgroup was showed before that. indexed array is so old, it's unlikely anyone could say who "came with it". Neither your method nor mine is from either of us, nor originally from Armin Zingler (whoever he is) and that fact goes without saying. These concepts predate .NET, Windows, and the PC. > Now nobody active in the Visual Basic newsgroup will think on other than What work-around methods? The correct top-down method is equivalent to the > bottom up methods for these problems, while they did before this top down, > with all those work around methods showed here. bottom-up method, and carries with it no greater degree of "work-around" than the bottom-up method. If "nobody active in the Visual Basic newsgroup will think on other than bottom up methods for these problems", then that's because nobody in that newsgroup understands that in programming, one size does not fit all. In reality, I doubt your assertion is true, but if it is, it's only proof of one-dimensional thinking, rather than the validity of your claim that one method is better than the other. Pete Peter Duniho wrote:
Show quote > "Cor Ligthert [MVP]" <notmyfirstn***@planet.nl> wrote in message Top-down or bottom-up, either way you have to worry. Top-down can> news:u7kiAQ97GHA.608@TK2MSFTNGP03.phx.gbl... > > No bottom up is easier, > > > > For (int i = mycollection.count - 1;i > -1;i--) > > { if (whatever) removeAt(i);} > > Just to be ornery, I'll point out that I like top down better: > > int i = 0 > while (i < mycollection.Count) > { > if (!whatever) > { > i++; > continue; > } > mycollection.RemoveAt(i); > } > > > :) > > (I actually do like that better, because the code is IMHO more readable; too > many "minuses" and "offsets by one" in the bottom up version for my tastes) > > Pete easily produce a hairy starting fencepost error because it's less commonly used. Bottom-up can produce nastier logic errors on removal. Imho, the DictionaryEntry<> should provide a "Remove" method that abstracts away the hairiness of iteration/removal from a dict. Likewise for lists, exposing a ListEntries enumerator that iterates across ListEntry<> objects that provide a similar feature. enumerator is invalidated. use:
while (dict.Count > 0) dict.RemoveAt(0); -- Show quoteMilosz Skalecki MCP, MCAD "Hyun-jik Bae" wrote: > Is there any efficient way doing Dictionary<>.RemoveAt in foreach { ... } > routine? > For example, is this example safe or is there any recommended way? > > foreach(KeyValuePair<int,int> a in mymap) > { > if(a.Value!=GoodValue) > { > mymap.RemoveAt(a.Key); // and continues the iteration > } > } > > Please reply. Thanks in advance. > > Hyun-jik Bae > > > |
|||||||||||||||||||||||