Link to home
Start Free TrialLog in
Avatar of Razzie_
Razzie_

asked on

Looping through Hashtable keys and setting their values

Heya,

This is probably easy - I just can't see it.

Let's say I have a Hashtable h filled with keys:

h.Add("value1", 0);
h.Add("value2", 0);
h.Add("value3", 0);

-----------------------------

Now, let's say I have this method:

private int doSomething(string bogus)
{ // do something and eventually return an integer }


How do I code it if the bogus parameter in doSomething would be the key of the hashtable, and the return value of the same method would be the new value for that key?

for(int i=0;i<h.Count;i++)
{
     // put all keys in hashtable through doSomething method and set the corresponding value to the return value
}


It is probably very simple, but can't see it :(

Thanks!

 
Avatar of chintan_vaishya
chintan_vaishya

Hi Heya,

You can Use this.
First create a class to Hold your value1,value2,value3 and 0,0,0.....etc.....

class hTableClass
{
public string value_whtever; //to hold value1,value2,value3.....etc

public hTableClass(string str1)
{
value_whtever=str1;
}

}

Hashtable hTable; //Declare a variable for HashTable        

//Now suppose you have created 3 objects for the class as below

hTableClass[] hobjects = new hTableClass[] {new hTableClass("Value1"),new hTableClass("Value2"),new hTableClass("Value3") };

hTable = new Hashtable(hobjects.Length);

//Adding Keys to Hashtable

foreach(hTableClass h in hobjects)
{
hTable.Add(h.value_whtever,h);
}


I hope this will be Useful.....
Good Luck.
Chintan
Avatar of Razzie_

ASKER

Sorry this is not what I was looking for. I am just looking for a clean and simple way of looping through my Hashtable and change values accordingly, I just don't know a good way of doing it, since I can't really use indexers [] it seems. I am just hoping that someone shows me how to loop through all keys and changing their values accordingly. Thanks, though.
Avatar of Razzie_

ASKER

Ok I *thought* I found out how I can do this:

foreach(string key in h.Keys)
{
      h[key] = doSomething(key);
}

------------------------------

That is how I had it in mind. Unfortunately I receive an error when I try this: Additional information: Collection was modified; enumeration operation may not execute.

I guess that is logical since you cannot change values during an enumeration? But I hope there is another pretty easy solution, or do I have to use Visitor pattern for this?

Thanks!
Razzie,  
   You are on the right track... just wrong object.  You want to use DictionaryEntry


         Hashtable ht = new Hashtable();
         ht.Add("1",1);
         ht.Add("2",1);
         ht.Add("3",1);

         foreach(DictionaryEntry de in ht)
            Console.WriteLine(de.Key);
ASKER CERTIFIED SOLUTION
Avatar of patsissons
patsissons

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Copy first the keys to an array:

object[] keysCopy = new object[h.Keys.Count];
h.Keys.CopyTo(keysCopy, 0);

foreach(string key in keysCopy)
{
     h[key] = doSomething(key);
}

Now you're iterating over the copy wich doesn't bother if you change the original collection. (But note that it will fail when you change a key value.)
Avatar of Razzie_

ASKER

ptmcomp: your solution is not working, since I tried that as stated in my previous post. I receive the error: "Collection was modified; enumeration operation may not execute" when i try that.

_TAD_: I can't see how that solution differs a lot from what I am trying. It's not a direct answer on my original question - how to set a value if I know the corresponding key.

I will accept the answer patsissions gave because that is closest to a solution to my problem (although I changed my program and am not using it anymore, but oh well ;).

Thanks, all.
I just tried out my version: No exception... Did you try it?
Avatar of Razzie_

ASKER

I apologize ptmcomp, I think I misread something because it does work... :( I don't think there is something to do about the points now, is there? If there is let me know, and thanks for your reply...
No, It's ok. I just wanted to know why it doesn't work in your case.
Did this get resolved?  I have similar questions on modified collections and enumerations.
@knowIton: Try to copy the key collection to a new array and iterate over this copy (see my example above).
Avatar of Razzie_

ASKER

Yep, ptmcomp's suggestion works :) As long as you don't change the collection when enumerating.
?? What do you mean by "As long as you don't change the collection when enumerating."?
Of course you will only iterate over the items which were in the collection by the time the copy was made and you need to be aware that items could have been removed. This is in the nature of a collection.
If you use indizes you have the same problems, but you probably will only notice some of the cases. E.g: You are iterating over a collection and accessing the index 3, then another thread inserts an item at position 1, after that our first thread accesses the item with the index 4 -> which is the same object as it accessed just before!
Avatar of Razzie_

ASKER

What you said in your own post: 'But note that it will fail when you change a key value'. Or any other way of modifying the collection when enumerating. For example, you can't add a new key to the collection when you're enumerating it. That's what I meant :)
Well, you could add a new value with my method but it wouldn't be enumerated. The question is what you are intended to do.
The problem is if we change the collection while enumerating it there are three scenarios what we expect:
- Stop enumerating and start again from the beginning for that you can use the way Microsoft implemented.
- Continue enumerating and handle the cases which will fail. This can be handled by similar code as I provided.
- Still enumerating the original collection. For this you would need a copy of the entire Hashtable in this case. Be aware that the values of the collection could be reference types and/or value types.
Thanks for the feedback so far!