I have a jagged dictionary:
Dictionary<string, Dictionary<int, Dictionary<string, string>>> tierOptions = new Dictionary<string, Dictionary<int, Dictionary<string, string>>>();
Later on, I have code that sets one of those values in the array:
tierOptions[optionID][npID]["tName"] = cboTier.Text;
The problem is that when it runs through this portion of code, all "tName" elements are set to cboTier.Text instead of just the one element.
For instance if optionID was 1 and npID was 8, and I had these three:
tierOptions[1][8]["tName"]
tierOptions[2][8]["tName"]
tierOptions[3][8]["tName"]
That particular line of code would set all three, instead of just tierOptions[1][8]["tName"]
Any idea why it is doing this? Thanks!
It sounds simply like you have used the same dictionary instance in several "dimensions" (your terminology). Since this is a reference, they are all shared (there is no automatic clone-into-isolated-copies here).
When filling the data, take care to use isolated dictionary instances when the data should be separate.
Yep, I would say the sae as Marc.
Please take a look at this example how you can retreive the vlaue from your type of Dictionary:
Dictionary<string, Dictionary<int, Dictionary<string, string>>> dic = new Dictionary<string, Dictionary<int, Dictionary<string, string>>>();
//add to 1st dic:
dic.Add("A", new Dictionary<int, Dictionary<string, string>>());
//add to 2nd dic:
dic["A"].Add(1, new Dictionary<string, string>());
//add to 3rd dic:
dic["A"][1].Add("a", "value 1");
//string KeyIn3rdDic = dic["A"][1].ToString();
string ValueIn3rdDic = dic["A"][1]["a"]; //result is "value 1";
Related
I have a dictionary < string,object > which has a mapping of a string and a dictionary < string,int >. How do I add a key value pair in the inside dictionary < string ,int > ?
Dictionary <string,object> dict = new Dictionary <string,object>();
Dictionary <string,int> insideDict = new Dictionary <string,int>();
// ad some values in insideDict
dict.Add("blah",insideDict);
So now the dict has a dictionary mapped with a string.Now I want to separately add values to the insideDict.
I tried
dict["blah"].Add();
Where am I going wrong?
Do you mean something like this?
var collection = new Dictionary<string, Dictionary<string, int>>();
collection.Add("some key", new Dictionary<string, int>());
collection["some key"].Add("inner key", 0);
Something like below
Dictionary<string, object> dict = new Dictionary<string, object>();
dict.Add("1", new Dictionary<string, int>());
(OR) if you already have defined the inner dictionary then
Dictionary<string, object> dict = new Dictionary<string, object>();
Dictionary<string, int> innerdict = new Dictionary<string, int>();
dict.Add("1", innerdict); // added to outer dictionary
string key = "1";
((Dictionary<string, int>)dict[key]).Add("100", 100); // added to inner dictionary
Per your comment tried this but screwed up somewhere
You didn't got it cause of your below line where you forgot to cast the inner dictionary value to Dictionary<string, int> since your outer dictionary value is object. You should rather have your outer dictionary declared strongly typed.
dict.Add("blah",insideDict); //forgot casting here
Dictionary<string, Dictionary<string,TValue>> dic = new Dictionary<string, Dictionary<string,TValue>>();
Replace the TValue with your value type.
This question already has answers here:
What is the best way to clone/deep copy a .NET generic Dictionary<string, T>?
(14 answers)
Closed 9 years ago.
I have four Dictionary , two are (dictionary within Dictionary), declaration shown below
Dictionary<string, Dictionary<string, string>> dict_set = new Dictionary<string, Dictionary<string, string>>();
Dictionary<string, Dictionary<string, string>> dict_Reset = new Dictionary<string, Dictionary<string, string>>();
Dictionary<string, string> set_value = new Dictionary<string, string>();
Dictionary<string, string> Reset_value = new Dictionary<string, string>();
I want to first add elements in dictionary set_vlaue and Reset_value.
once the values are added then i am adding these dictionaries to other two dictionaries as shown below.
dict_set.Add(condiName, set_value);
dict_Reset.Add(condiName, Reset_value);
set_value.Clear();
Reset_value.Clear();
the values are getting added , but after adding set_value and reset_value dictionaries , i want to clear these two dictionaries set_value and reset_value,but problem occurs that when set_value and reset_value are cleared the data from dict_set and dict_reset is also cleared..
can any one help me , to how to create deep copy of dictionaries in this case...
I do not know what you are trying to do in the workflow, but why not to reinstancing instead of cleaning?
dict_set.Clear();
to:
dict_set = new Dictionary<string, string>();
Aside of what Skeet has written in the answer pointed out by keyboardP, in most managed languages you may very easily perform deep copy by:
serializing the thing
deserializing it back
Upon deserialization, you'll usually have a complete deep clone of the original. The serializer will usually do all the ID-checking, breaking cycles, deduplicating, etc. In your case this is not necessary, but it may came handy later.
You may serialize it to XML, BinaryForm, JSON or whatever you like and have at hand. It is not that important.
Now back to your question:
This is your code, just shortened a bit:
var dict_set = new Dictionary<string, Dictionary<string, string>>();
var dict_Reset = new Dictionary<string, Dictionary<string, string>>();
var set_value = new Dictionary<string, string>();
var Reset_value = new Dictionary<string, string>();
dict_set.Add(condiName, set_value);
dict_Reset.Add(condiName, Reset_value);
set_value.Clear();
Reset_value.Clear();
You claim that:
(...) but problem occurs that when set_value and reset_value are cleared the data from dict_set and dict_reset is also cleared..
This is not true. With that code of above, it is not possible. set/reset/dict_set/dict_reset are 4 distinct objects. Calling "Clear" on "set/reset" cannot cause the others to be cleared.
Look at your code. The error is elsewhere. Not here. Something other is clearing that dict* dictionaries.
By creating new instance will solve the above issue.. if any one came across some other better solution please post..
dict_set.Add(condiName, new Dictionary<string, string>(set_value));
dict_Reset.Add(condiName, new Dictionary<string, string>(Reset_value));
set_value.Clear();
Reset_value.Clear();
I think this way the inner dictionaries in dict_set and dict_Reset will not be cleared
dict_set.Add(condiName, set_value.ToDictionary(entry => entry.Key,entry => entry.Value));
dict_Reset.Add(condiName, Reset_value.ToDictionary(entry => entry.Key,entry => entry.Value));
set_value.Clear();
Reset_value.Clear();
With the ToDictionary() method you actually create a new Dictionary object, not using the reference to tour originals dictionaries anymore, so you can safely clear them.
Adding and removing data to the set_value and Reset_value alsdo does not affect the dictionaries inside dict_set and dict_Reset
Just out of curiousity, why Reset_value with a capital S and set_value not?
I have a the following code -
Dictionary<string, string> myDict = new Dictionary<string, string>();
myDict.Add("keyA", "valueA");
myDict.Add("keyB", "valueB");
IEnumerable<SelectListItem> mySelectList = new SelectList(myDict, "key", "value")
Further down in the program, I want to add values to myDict. Is that possible? If yes, then how?
I want to do something like -
mySelectList.myDict.Add("keyC", "valueC");
If you're wanting to add items to myDict, this is certainly possible, and any changes will be reflected in any of mySelectList's enumerations as long as the changes are made before the enumeration (e.g. using .ToList()) is generated.
As a worked example:
Dictionary<string, string> myDict = new Dictionary<string, string>();
myDict.Add("keyA", "valueA");
myDict.Add("keyB", "valueB");
IEnumerable<SelectListItem> mySelectList = new SelectList(myDict, "key", "value");
myDict.Add("keyC", "valueC");
var result = mySelectList.ToList();
// result is now a list containing three items - keyA, keyB and keyC.
myDict.Add("keyD", "valueD");
var result2 = mySelectList.ToList();
// result2 is a list containing four items. result is
// unchanged, containing just the original three.
Try something horrendous like this:
((Dictionary<string, string>)mySelectList.Items).Add("keyC", "valueC");
It would be better if you just kept the reference to myDict around in your own code, though, rather than abusing their property.
Note: It's very possible this doesn't work. I haven't tried it.
Currently i have a mapping setup like this
//Identifiers to save (currently)
Dictionary<string, Dictionary<string, string>> toSaveIdentifiers =
new Dictionary<string, Dictionary<string, string>>(); //
however, i want to add an extra dimension to it because i just missed out on an extra attribute to add.
I'm trying to set up some form of mapping that gets populated frequently in a program and is looked up throughout the program as well. I was wondering what is the best way to go about doing this.
//Identifiers to save (tuple)
Dictionary<Tuple<string,string>, Dictionary<string, string>> toSaveIdentifiers =
new Dictionary<Tuple<string, string>, Dictionary<string, string>>(); //
//Identifiers to save (adding another dictionary dimension)
Dictionary<string, Dictionary<string,Dictionary<string, string>>> toSaveIdentifiers =
new Dictionary<string, Dictionary<string, Dictionary<string, string>>>(); //
//Identifiers to save (adding keyvaluepair)
Dictionary<KeyValuePair<string,string>, Dictionary<string, string>> toSaveIdentifiers =
new Dictionary<KeyValuePair<string, string>, Dictionary<string, string>>(); //
When i populate it/lookup i do something like.
// check identifier map dictionary
if (dictionary.Keys.Contains(identifier))
{
if (dictionary[identifier].Keys.Contains(currency))
{
//stuff
}
else
{
//stuff
}
}
else
{
//more stuff
}
What would be the best method of doing this for lookup?
Since your identifiers all seem to be of type string, you could always just concat them all into one big string and use that as the key. Then instead of doing the nested Contains, you'd just have to do one. It'd also be more flexible as far a storing different levels of identifiers.
i.e. Given a 2 level key, it'd be
string ident = level1Identifier + "." + level2Identifier;
(using string.format() or StringBuilder would be more efficient, but this code is better for explaining)
Also consider the joining character should be something you know won't show up in any levels identifier to avoid confusion or accidently duplicates.
I would like to use something like this:
Dictionary<int, string>[] matrix = new Dictionary<int, string>[2];
But, when I do:
matrix[0].Add(0, "first str");
It throws " 'TargetInvocationException '...Exception has been thrown by the target of an invocation."
What is the problem? Am I using that array of dictionaries correctly?
Try this:
Dictionary<int, string>[] matrix = new Dictionary<int, string>[]
{
new Dictionary<int, string>(),
new Dictionary<int, string>()
};
You need to instantiate the dictionaries inside the array before you can use them.
Did you set the array objects to instances of Dictionary?
Dictionary<int, string>[] matrix = new Dictionary<int, string>[2];
matrix[0] = new Dictionary<int, string>();
matrix[1] = new Dictionary<int, string>();
matrix[0].Add(0, "first str");
Dictionary<int, string>[] matrix = new Dictionary<int, string>[2];
Doing this allocates the array 'matrix', but the the dictionaries supposed to be contained in that array are never instantiated. You have to create a Dictionary object in all cells in the array by using the new keyword.
matrix[0] = new Dictionary<int, string>();
matrix[0].Add(0, "first str");
You've initialized the array, but not the dictionary. You need to initialize matrix[0] (though that should cause a null reference exception).
You forgot to initialize the Dictionary. Just put the line below before adding the item:
matrix[0] = new Dictionary<int, string>();