如何迭代遍历字典列表?

4

我有以下代码:

List<Dictionary<string, string>> allMonthsList = new List<Dictionary<string, string>>();
while (getAllMonthsReader.Read()) {
    Dictionary<string, string> month = new Dictionary<string, string>();
    month.Add(getAllMonthsReader["year"].ToString(),
    getAllMonthsReader["month"].ToString());
    allMonthsList.Add(month);
}
getAllMonthsReader.Close();

现在我正在尝试遍历所有月份,如下所示:
foreach (Dictionary<string, string> allMonths in allMonthsList)

我该如何访问关键值?我做错了什么吗?
3个回答

15
foreach (Dictionary<string, string> allMonths in allMonthsList)
{
    foreach(KeyValuePair<string, string> kvp in allMonths)
     {
         string year = kvp.Key;
         string month = kvp.Value;
     }
}

顺便说一下,一年通常有多个月份。看起来你需要一个查找表,或者使用Dictionary<string, List<string>> 存储所有的月份。

解释 泛型字典Dictionary<TKey, TValue> 实现了IEnumerable接口,该接口返回一个枚举器,用于遍历集合。来自msdn:

对于枚举的目的,字典中的每个项都被视为表示其键和值的KeyValuePair<TKey, TValue>结构。项的返回顺序是未定义的。

C#语言的foreach语句要求集合中每个元素的类型。 由于Dictionary<TKey, TValue> 是一个键和值的集合, 元素类型不是键的类型或值的类型。 相反,元素类型是键类型和值类型的KeyValuePair<TKey, TValue>


allMnths 来自哪里? - John Isaiah Carmona
@eric.itzhak 你添加了内部的foreach吗? - Sergey Berezovskiy
是的,我有。这只返回“年”而不是“月”,我尝试使用ToString()但没有成功。 - eric.itzhak
@JohnIsaiahCarmona 谢谢,那是个简单的打字错误(我通常不使用Visual Studio来回答问题,因此看不到打字错误)。 - Sergey Berezovskiy
@eric.itzhak 稍等,马上会有解释 :) - Sergey Berezovskiy
显示剩余3条评论

3
var months = allMonthsList.SelectMany(x => x.Keys);

然后,您可以按照自己的意愿遍历 IEnumerable<string>,它是您所有键的简单枚举。


或者,如果您想直接遍历KeyValuePair,则可以使用allMonthsList.SelectMany(x => x) - Dan Field

1

你的设计有问题。在字典中只使用一对是没有意义的。你不需要使用字典列表。

试试这个:

class YearMonth
{
    public string Year { get; set; }
    public string Month { get; set; }
}

List<YearMonth> allMonths = List<YearMonth>();
while (getAllMonthsReader.Read())
{
     allMonths.Add(new List<YearMonth> {
                            Year = getAllMonthsReader["year"].ToString(),
                            Month = getAllMonthsReader["month"].ToString()
                                        });
}

getAllMonthsReader.Close();

用作:

foreach (var yearMonth in allMonths)
{
   Console.WriteLine("Year is {0}, Month is {1}", yearMonth.Year, yearMonth.Month);
}

或者,如果您使用的是 .Net Framework 4.0 或更高版本,您可以使用元组(Tuple)。

List<Tuple<string, string>> allMonths = List<Tuple<string, string>>();
while (getAllMonthsReader.Read())
{
     allMonths.Add(Tuple.Create( getAllMonthsReader["year"].ToString(),
                                 getAllMonthsReader["month"].ToString())
                  );
}

getAllMonthsReader.Close();

然后使用:

foreach (var yearMonth in allMonths)
{
   Console.WriteLine("Year is {0}, Month is {1}", yearMonth.Item1, yearMonth.Item2);
}

1
这并不一定是无意义的 - 如果直到运行时才知道字段数量怎么办?所有你的建议都需要在编译时知道这些信息(如果月份列表只是简单的1-12月,那么这个方法可以工作,但如果它是一个由重复月份和其他从输入读取的数据组成的列表,则不行)。 - Dan Field

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