简体   繁体   中英

Iterating over dictionay inside dictionary

I am try to iterate over a dictionary Dictionary<uint,Dictionary<uint,uint>> myDict .

I want to change value of internal dictionary.

When I use:

foreach(var item in myDict)
{
    foreach(var rt in item)

I get the error:

Severity Code Description Project File Line Suppression State Error CS1579 foreach statement cannot operate on variables of type 'KeyValuePair<uint, Dictionary<uint, uint>>' because 'KeyValuePair<uint, Dictionary<uint, uint>>' does not contain a public instance definition for 'GetEnumerator' SparrowView

Why can't I enumerate inside?

Please try using item.Value .

As you are currently iterating over both uints and the dictionary, not only the dictionary.

The way you using foreach in very iteration you get KeyValuePair , which can't be iterated over, as error states.

So you need the value inside outer foreach , which would be the Dictionary you can iterate over, something like this:

foreach(var item in myDict)
{
    foreach(var rt in item.Value)
    {
        ...
    }
}

Also, you could use myDict.SelectMany(kvp => kvp.Value).ToArray(); which would return array with all key and value pairs from all dictionaries, then you can iterate over all of them at once (without nesting loops).

If you're looking for a particular key in the inner dictionary it might make more sense to you to look through the keys collection and address your dictionaries by key:

foreach(var outerKey in myDict.Keys)
{
   foreach(var innerKey in myDict[outerKey].Keys)
   {
     if(innerKey == 3)
       ...
   }
}

Alternatively, if you iterate a dictionary directly you get a keyvaluepair, so you have to keep straight in your mind the difference between a key (uint) and a value (a dictionary in your outer, a uint in your inner)

foreach(var outerKvp in myDict) //foreaching the outer dictionary gives a keyvaluepair, the value of which is a dictionary
{
   foreach(var innerKvp in outerKvp.Value) //outerKvp.Value is a Dictionary<uint,uint), foreaching it will again give you a keyvaluepair, this time for the inner dictionary. the value this time is a uint
   {
     if(innerKvp.Key == 3)
       ...
   }
}

Also bear in mind if you're looking to modify either of these you can't do it inside a for loop because you can't modify a dictionary you're enumerating over. In such cases it might be better to just use ContainsKey:

//for example if you know the outer key
if(myDict.ContainsKey(1) && myDict[1].ContainsKey(3))
    myDict[1][3] = 4;

//or if you don't know the outer key
foreach(var outerKey in myDict.Keys)
{
   if(myDict[outerKey].ContainsKey(3))
       myDict[outerKey][3] = 4; //this will succeed because we aren't enumerating the inner dict
}

Consider carefully whether this is the best data storage container for your needs; it's slightly convoluted to have a dictionary of dictionaries and you might do better making a compound key out of your uints and using a single dictionary or picking on another data storage container all together

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM