Enumerating Hashtables

A lengthy thread was started about enumerating a hashtable and modifying the values.  The individual was getting the standard modification within a foreach exception thrown.  I had suggested the following code and I seem to have the shortest and easiest method in doing so...

ArrayList arrayList = new ArrayList(hashtable.Keys);
IEnumerator listEnumerator = arrayList.GetEnumerator();
while (listEnumerator.MoveNext()) {
    hashtable[listEnumerator.Current] = "value";
} // while

Is there a better or recommended way to do this?  The above seemed right to me.

UPDATE:  Jerry Pisk had suggested that I was doing extra code when you can just enumerate using foreach and modify the values.  That was the whole point of me writing the first paragraph above Jerry.  Doing that causes an exception.  You can enumerate all day long and “read” values, but you can not modify the values within the foreach loop.  Which brings you to the code I wrote above...

Published Saturday, February 07, 2004 10:32 AM by bstahlhood
Filed under:

Comments

# re: Enumerating Hashtables

Why do you create an extra ArrayList object? ICollection is enumerable, you can enumerate the Keys directly instead of creating an extra ArrayList object:

foreach( Object iKey in hashtable.Keys )
{
hashtable[iKey] = "value";
}

It's faster and uses less memory (since it doesn't copy the keys collection into an ArrayList).

Saturday, February 07, 2004 3:53 PM by Jerry Pisk

# re: Enumerating Hashtables

Did you even try the code you are suggesting? Will not work Jerry ;)

Saturday, February 07, 2004 5:01 PM by Ben S. Stahlhood II

# re: Enumerating Hashtables

Very nice, though I'd personally just an array:

object[] array = new object[hashtable.Keys.Count];
hashtable.Keys.CopyTo(array, 0);
foreach (object key in array) {
hashtable[key] = "value";
}

Using a foreach here does work, right? Is there a reason you used a while statement?

Saturday, February 07, 2004 6:44 PM by David Bossert

# re: Enumerating Hashtables

And that, folks, is why you should never respond to blog posts right after waking up.

Saturday, February 07, 2004 6:47 PM by David Bossert

# re: Enumerating Hashtables

Noting the work done by the ArrayList I propose the following which is somewhat quicker than the method of enumerating the ArrayList. Note that internally the ArrayList is allocating an array and doing a CopyTo.

private static void EnumerateHash2(Hashtable hashtable) {
object[] keys = new object[hashtable.Keys.Count];
hashtable.Keys.CopyTo(keys, 0);
for(int i = 0; i < keys.Length; i++) {
hashtable[keys[i]] = "value";
}
}

After finding this method, I figured, why not try the enumerator over top of the object[], and that comes out even faster.

private static void EnumerateHash4(Hashtable hashtable) {
object[] keys = new object[hashtable.Keys.Count];
hashtable.Keys.CopyTo(keys, 0);
foreach(object o in keys) {
hashtable[o] = "value";
}
}

Thought about going to unsafe code and make it even faster, but that is just crazy talk.

Saturday, February 07, 2004 6:52 PM by Justin Rogers

# re: Enumerating Hashtables

Ok, I think this is a bug in Hashtable implementation as we do NOT modify the keys collection by assigning an existing key new value. This whole thread is a nice example of developers trying to work around a bug.

Sunday, February 08, 2004 12:10 AM by Jerry Pisk

# re: Enumerating Hashtables

This might not be the most performant variant, but I think it is the most readable:

foreach( object key in new ArrayList(hashtable.Keys) )
{
hashtable[key] = "value";
}

Sunday, February 08, 2004 7:22 AM by Nicko

# re: Enumerating Hashtables

How about:

IDictionaryEnumerator myEnum = hashtable.GetEnumerator();

while(myEnum.MoveNext())
{
hashtable[myEnum.Key] = "value";
}

Sunday, February 08, 2004 8:11 PM by James High

# re: Enumerating Hashtables

We have Hashtable:

Rule Flow (r1,r2) is an arraylist..

Ruleid Rule Flow (arraylist)

R01 r1, r2, r3, r4

R02 r5, r6

How to extract the values of r1, r2, r3, r4 using Rule
id in Hashtable

Can u suggest something!!!


Friday, June 11, 2004 6:47 AM by Mohit

# re: Enumerating Hashtables

We have Hashtable:

Rule Flow (r1,r2) is an arraylist..

Ruleid Rule Flow (arraylist)

R01 r1, r2, r3, r4

R02 r5, r6

How to extract the values of r1, r2, r3, r4 using Rule
id in Hashtable

Can u suggest something!!!


Friday, June 11, 2004 6:47 AM by Mohit

# re: Enumerating Hashtables

I am having a hard time understanding your post. Could you please be more clear or post some sample code of what you are tyring to accomplish.

Thanks

Sunday, June 13, 2004 7:44 AM by Ben S. Stahlhood II

# re: Enumerating Hashtables

If you just want to loop through, you can also try

foreach (DictionaryEntry item in hash)  

{    

      item.Value  = "value";

}

isn't it quite a clean code?

Thursday, August 31, 2006 3:16 PM by Wander

# re: Enumerating Hashtables

@Wander:

Did you try that code?  Cause it will not work.

Thursday, August 31, 2006 4:18 PM by bstahlhood

Leave a Comment

(required) 
(required) 
(optional)
(required)