如何在foreach循环中访问嵌套的Dictionary<>对象

5

我有一个嵌套字典结构,像这样:

Dictionary<string, Dictionary<string, string>> dict;

我试图使用两个foreach循环访问元素,但编译器不允许我将以下内容用作内部循环的循环变量:

Dictionary<string, string>

这是我的内容:

这是我所拥有的:

foreach (string key in dict.Keys) {
    foreach (Dictionary<string, string> innerDict in dict[key]) {
        // ...
    }
}

编译器提示:
Cannot convert type 'System.Collections.Generic.KeyValuePair<string,string>'
 to 'System.Collections.Generic.Dictionary<string,string>'

我可以在内部循环中使用KeyValuePair <string,string>,但我想作为一个整体访问字典对象本身(这样我就可以像这样做:if(dict.ContainsKey(innerDict)){...})。

7个回答

5
最小的代码更改来修复它如下(但请查看本答案中下一个代码片段的正确方法):
Dictionary<string, Dictionary<string, string>> dict;

foreach (string key in dict.Keys)
{
    foreach (var innerDict in dict[key].Select(k => k.Value))
    {
    }
}

你的问题在于遍历字典时,得到一个键/值对序列。在你的情况下,值是内部字典,而正是那个你所需要的。
我使用Linq的“Select()”操作来将每个键/值对转换为仅有的值部分,也就是键/值对中的值,也就是字典。
然而,这是一种冗长而低效的方式,用于获取每个内部字典以及它的键。以下是应该如何完成此操作的方法:
foreach (var item in dict)
{
    string key = item.Key;
    Dictionary<string, string> innerDict = item.Value;

    // Do something with key and innerDict.
}

我假设您想依次访问每个内部字典,同时知道外部字典中该内部字典的键。
请注意,我只复制了item.Keyitem.Value的值到本地变量以说明它们的类型。当然,您也可以直接使用item.Keyitem.Value
如果您真的只想要内部字典本身(而不需要每个内部字典的键),您可以像Nuffin建议的那样这样做:
foreach (var innerDict in dict.Values)
{
    // Use inner dictionary
}

你应该知道字典有一个“Values”属性,它可以直接访问存储的值,对吧? - Nuffin
@Nuffin 我认为他想要使用外部字典键和内部字典,所以我建议采用第二种方法。对于第一种方法,我只是纠正了语法错误。 - Matthew Watson

1
那是因为“string”键的值不是一个列表。如果你想要的话,将“Dictionary”的声明更改为“Dictionary<string, List<Dictionary<string, string>>> dict;”。或者你可以像这样在第一个“foreach”循环中获取字典:
Dictionary<string, string> val = dict[key];

你想从那里使用它。但无论哪种方式,你都在尝试迭代不可枚举的内容。

我认为你可能已经按照自己的需求定义了字典(Dictionary)——你只是不需要内部循环。


@Ted,抱歉,当我查看问题时,我看到了一个&lt;字符。 - Mike Perrenoud
@user2455816,抱歉,当我查看问题时,我看到了一个&lt;字符。 - Mike Perrenoud
@Renan,抱歉,当我查看问题时,我看到了一个&lt;字符。 - Mike Perrenoud

1
您可以通过使用以下代码来简短地表达:

您可以通过使用以下代码来简短地表达:

foreach (Dictionary<string, string> d in dict.Values) {
}

它可以工作,编译器没有任何抱怨。

另外请注意,在这种情况下,你的代码不起作用,因为dict[key]不是字典集合,而是单个字典。


1

我认为你误解了底层的字典结构。

Dictionary<string, Dictionary<string, string>>

上述代码导致父级包含一个字典对象。当您尝试在此对象上使用foreach时,编译器不知道该怎么做。如果您使用以下代码,可能更容易理解。
Dictionary<string,string> dictionaryObject;
foreach (string item in dictionaryObject)
{ }

上述操作也会导致相同的错误。
您可以通过迭代字典对象的键或值来解决问题,例如,
foreach (string  key in dict.Keys)
{
    foreach (string innerKey in dict[key].Keys)
    {
        System.Diagnostics.Debug.WriteLine(dict[key][innerKey]);
    }
}

0

即使您使用KVP,仍然可以像您希望的那样引用字典。 请尝试以下操作:

foreach (var outerKVP in dict {
    foreach (var innerKVP in dict[outerKVP.Key]) {
        var theString = dict[outerKVP.Key][innerKVP.Key];
    }
}

0
foreach (Dictionary<string, string> innerDict in dict[key]) {
        // ...
    }

这个失败是因为dict[key]是一个Dictionary<string,string>,所以使用foreach枚举它将产生KeyValuePair<string,string>类型的元素。

如果你想访问内部字典,只需这样做并删除foreach循环即可。

Dictionary<string, string> innerDict = dict[key];

0

应该不难:

Dictionary<string, Dictionary<string, string>> dict = new Dictionary<string,Dictionary<string,string>>();

foreach (var kvp in dict)
{
    var innerDict = kvp.Value;

    foreach (var innerKvp in innerDict)
    {
        Console.WriteLine(kvp.Key + " " + innerKvp.Key + " " + innerKvp.Value);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接