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

Remove Values From Dictionary while Looping Through Values

P: n/a
I need the ability to parse through the values of a Dictionary and
remove certain ones depending on their attribute values. In the example
below, an InvalidOperationException is thrown in the foreach statement
when the first item is removed from the Dictionary.

From looking at Dictionary's methods, I couldn't find anything to
create a copy of the Values before starting the foreach loop. Help?
static void someTest() {
Dictionary<String, Int32storage = new Dictionary<string, Int32>();
for (int i = 0; i < 100; i++) {
String bar = "Test" + i;
Int32 foo = new Int32();
foo = i;
storage.Add(bar, foo);
}
foreach (Int32 tmp in storage.Values) {
if ((tmp % 5) == 0) {
String bar = "Test" + tmp;
storage.Remove(bar);
}
}
}
Nov 1 '06 #1
Share this Question
Share on Google+
4 Replies


P: n/a
"O.B." <fu******@bellsouth.neta écrit dans le message de news:
12*************@corp.supernews.com...

|I need the ability to parse through the values of a Dictionary and
| remove certain ones depending on their attribute values. In the example
| below, an InvalidOperationException is thrown in the foreach statement
| when the first item is removed from the Dictionary.

You cannot modify any list that is running an enumerator of iterator. You
need to use :

for (int i = list.count - 1; i >= 0; i--)
...

to ensure that items removed do not upset the iteration.

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Nov 2 '06 #2

P: n/a
"O.B." <fu******@bellsouth.netwrote in message
news:12*************@corp.supernews.com...
>I need the ability to parse through the values of a Dictionary and remove
certain ones depending on their attribute values. In the example below, an
InvalidOperationException is thrown in the foreach statement when the first
item is removed from the Dictionary.

From looking at Dictionary's methods, I couldn't find anything to create a
copy of the Values before starting the foreach loop. Help?
You cannot modify a container without invalidating all active enumerators -
hence breaking your foreach statement. For a dictionary, what you need to
do is to build a list of keys to be deleted, then use a second loop through
that list to remove items from the dictionary.

static void someTest() {
Dictionary<String, Int32storage = new Dictionary<string, Int32>();
for (int i = 0; i < 100; i++) {
String bar = "Test" + i;
Int32 foo = new Int32();
foo = i;
storage.Add(bar, foo);
}

List<stringkeysToDelete = new List<string>();
foreach (Int32 tmp in storage.Values) {
if ((tmp % 5) == 0) {
String bar = "Test" + tmp;
keysToDelete.Add(bar);
}
}
foreach (string key in keysToDelete) {
storage.Remove(key);
}
}

-cd
Nov 2 '06 #3

P: n/a
Carl Daniel [VC++ MVP] wrote:
"O.B." <fu******@bellsouth.netwrote in message
news:12*************@corp.supernews.com...
>I need the ability to parse through the values of a Dictionary and remove
certain ones depending on their attribute values. In the example below, an
InvalidOperationException is thrown in the foreach statement when the first
item is removed from the Dictionary.

From looking at Dictionary's methods, I couldn't find anything to create a
copy of the Values before starting the foreach loop. Help?

You cannot modify a container without invalidating all active enumerators -
hence breaking your foreach statement. For a dictionary, what you need to
do is to build a list of keys to be deleted, then use a second loop through
that list to remove items from the dictionary.

static void someTest() {
Dictionary<String, Int32storage = new Dictionary<string, Int32>();
for (int i = 0; i < 100; i++) {
String bar = "Test" + i;
Int32 foo = new Int32();
foo = i;
storage.Add(bar, foo);
}

List<stringkeysToDelete = new List<string>();
foreach (Int32 tmp in storage.Values) {
if ((tmp % 5) == 0) {
String bar = "Test" + tmp;
keysToDelete.Add(bar);
}
}
foreach (string key in keysToDelete) {
storage.Remove(key);
}
}
This got me going in the right direction. The following is a little
more compact:

Given entityDatase as a Dictionary<long, MyClass>:

MyClass[] tempList = new MyClass[entityDatabase.Count];
entityDatabase.Values.CopyTo(tempList, 0);

foreach (MyClass tmp in tempList) {
if (tmp.invalid) {
entityDatabase.Remove(tmp);
}
}
Nov 3 '06 #4

P: n/a

O.B. wrote:
Carl Daniel [VC++ MVP] wrote:
"O.B." <fu******@bellsouth.netwrote in message
news:12*************@corp.supernews.com...
I need the ability to parse through the values of a Dictionary and remove
certain ones depending on their attribute values. In the example below, an
InvalidOperationException is thrown in the foreach statement when the first
item is removed from the Dictionary.

From looking at Dictionary's methods, I couldn't find anything to create a
copy of the Values before starting the foreach loop. Help?
You cannot modify a container without invalidating all active enumerators -
hence breaking your foreach statement. For a dictionary, what you need to
do is to build a list of keys to be deleted, then use a second loop through
that list to remove items from the dictionary.

static void someTest() {
Dictionary<String, Int32storage = new Dictionary<string, Int32>();
for (int i = 0; i < 100; i++) {
String bar = "Test" + i;
Int32 foo = new Int32();
foo = i;
storage.Add(bar, foo);
}

List<stringkeysToDelete = new List<string>();
foreach (Int32 tmp in storage.Values) {
if ((tmp % 5) == 0) {
String bar = "Test" + tmp;
keysToDelete.Add(bar);
}
}
foreach (string key in keysToDelete) {
storage.Remove(key);
}
}

This got me going in the right direction. The following is a little
more compact:

Given entityDatase as a Dictionary<long, MyClass>:

MyClass[] tempList = new MyClass[entityDatabase.Count];
entityDatabase.Values.CopyTo(tempList, 0);

foreach (MyClass tmp in tempList) {
if (tmp.invalid) {
entityDatabase.Remove(tmp);
}
}
Well, yes, it's more compact, but it ends up copying a lot more
information than it has to. Carl's solution is one of the two
"standard" solutions to this problem, the other one given by Joanna is
iterating through a list in reverse. For the case of a Dictionary I
would choose Carl's method.

Nov 3 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.