Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C# (http://www.go4expert.com/articles/c-sharp-tutorials/)
-   -   .Net collections enumeration (http://www.go4expert.com/articles/net-collections-enumeration-t8914/)

shabbir 19Feb2008 18:54

.Net collections enumeration
 

Introduction



I happen to edit the collections many times in the foreach loop and run into problems and then each time I got a different solution when going to Google, So first I would try to list each of the solution and then discuss them so that we all can have the best practice in the collection iteration. Please note that I am not saying the one I have mentioned is the best but I found it to be one of the best for my context.

Background



Recently I cam across an exception as Collection was modified; enumeration operation may not execute. and the sample code which can throw such exception is
Code: CSharp

ArrayList list = new ArrayList();
list.Add("123");
list.Add("456");
list.Add("789");
list.Add("741");
list.Add("852");

foreach (string s in list)
{
    if (s == "789")
    {
        list.RemoveAt(list.IndexOf("789"));
    }
}

As a C++ background programmer I normally use to do the same in C++ with arrays and I continued the same in C-Sharp as well but ran into problem with the exception.

Solution 1 : Convert collection to Array



Code: CSharp

foreach (string s in list.ToArray())
{
    if (s == "789")
    {
        list.RemoveAt(list.IndexOf("789"));
    }
}

The method is not very efficient because you are not using the collection but using the arrays and is not good for large collections.

Solution 2 : Use for loop instead foreach.


Code: CSharp

int cnt = list.Count - 1;
for (int i = 0; i < cnt; )
{
    string s = (string)list[i];
    System.Console.WriteLine(s);
    if (s == "789")
    {
        list.RemoveAt(i);
    }
    else
    {
        i++;
    }
}

There are many disadvantages to the above method. One being if you are removing then you should not increment the counter when you are removing or else you will miss the next element after the removed index. Here it would be 741 which is after 789 and the other one being you are always looping through the count -1 initially which is not the case when you add / remove it and so you need to take all the pain to make sure it loops as expected with lots of if's and else's.

Solution 3 : Mark all the element.



Mark all the elements you wish to remove and then iterate through the marked object to remove them.
Code: CSharp

ArrayList indexListToRemove = new ArrayList();
foreach (string s in list)
{
    if (s == "789")
    {
        indexListToRemove.Add(s);
    }
}
foreach (string s in indexListToRemove)
{
    list.Remove(s);
}

Summary



You should avoid changes to collections (in fact most cases you will not even be able to change the collection) using foreach.

venkatesanj@hcl.in 4Mar2008 08:43

Re: .Net collections enumeration
 
Shabbir,

I think you dealt only with list collection. I will try to post my articles on other .net collections.

Regards,
Venkatesan Prabu. J

shabbir 4Mar2008 09:20

Re: .Net collections enumeration
 
Yup

shabbir 5Mar2008 09:42

Re: .Net collections enumeration
 
Nominate your favorite article of the month for Feb 2008

aisha.ansari84 5Mar2008 17:28

Re: .Net collections enumeration
 
Quote:

Originally Posted by venkatesanj@hcl.in
Shabbir,

I think you dealt only with list collection. I will try to post my articles on other .net collections.

Regards,
Venkatesan Prabu. J

yes all the others are equivalently important

shabbir 18Mar2008 17:35

Re: .Net collections enumeration
 
Vote for article of the month for Feb 2008


All times are GMT +5.5. The time now is 17:07.