【问题标题】:How can I iterate through a dictionary that contains a dictionary that contains another dictionary which contains a list如何遍历包含一个字典的字典,该字典包含另一个字典,该字典包含一个列表
【发布时间】:2019-06-21 15:48:25
【问题描述】:

我想更改列表中对象的值。 List 本身在字典中,字典在字典中,字典在字典中。我是否必须分别遍历它们中的每一个?我尝试了多次 foreach,但没有成功。

这是字典:

public static Dictionary<int,Dictionary<int,Dictionary<int,List<EventObj>>>> events_list; // <Year,<Month,<Day,Number of Events>>>

【问题讨论】:

  • 现在,您为什么要这样做?如果您以这种方式嵌套这些泛型类型,则通常表明您正在滥用它们。您最好构建一些自定义类型来表示实际结构,这也将使导航变得更加容易,不仅对您而言,对未来的开发人员也是如此。

标签: c# list dictionary


【解决方案1】:

对于这种场景,我个人更喜欢SelectMany

IEnumerable<EventObj> eventObjects = events_list
    .SelectMany(x => x.Value)
    .SelectMany(x => x.Value)
    .SelectMany(x => x.Value);

foreach (EventObj eventObject in eventObjects)
{
    // change the object
}

如果你喜欢这种事情,或者作为查询语法.. ;)

IEnumerable<EventObj> eventObjects =
    from years in events_list
    from months in years.Value
    from days in months.Value
    from events in days.Value
    select events;

foreach (EventObj eventObject in eventObjects)
{
    // change the object
}

【讨论】:

    【解决方案2】:
    foreach(var year in events_list.Keys)
        foreach(var month in events_list[year].Keys)
             foreach(var day in events_list[year][month].Keys)
                 foreach(var eventObject in events_list[year][month][day])
                 {
                     // do stuff
                 }
    

    这应该可以工作

    【讨论】:

      【解决方案3】:

      使用这样的复杂结构可能会变得尴尬和令人沮丧。我建议您创建自己的继承自该结构的类,以封装在结构中添加数据并枚举其条目的逻辑。这是一个基本的实现:

      public class YearMonthDayTree<T>
          : Dictionary<int, Dictionary<int, Dictionary<int, List<T>>>>
      {
          public void Add(int year, int month, int day, T item)
          {
              if (!this.TryGetValue(year,
                  out Dictionary<int, Dictionary<int, List<T>>> yearDict))
              {
                  yearDict = new Dictionary<int, Dictionary<int, List<T>>>(12);
                  this[year] = yearDict;
              }
              if (!yearDict.TryGetValue(month, out Dictionary<int, List<T>> monthDict))
              {
                  monthDict = new Dictionary<int, List<T>>(31);
                  yearDict[month] = monthDict;
              }
              if (!monthDict.TryGetValue(day, out List<T> dayList))
              {
                  dayList = new List<T>();
                  monthDict[day] = dayList;
              }
              dayList.Add(item);
          }
      
          public IEnumerable<(int Year, int Month, int Day, T Item)> Flatten()
          {
              foreach (var yearEntry in this)
              {
                  int year = yearEntry.Key;
                  foreach (var monthEntry in yearEntry.Value)
                  {
                      int month = monthEntry.Key;
                      foreach (var dayEntry in monthEntry.Value)
                      {
                          int day = dayEntry.Key;
                          foreach (var item in dayEntry.Value)
                          {
                              yield return (year, month, day, item);
                          }
                      }
                  }
              }
          }
      }
      

      使用示例:

      var events_list = new YearMonthDayTree<EventObj>();
      events_list.Add(2019, 6, 21, new EventObj());
      events_list.Add(2019, 6, 22, new EventObj());
      events_list.Add(2019, 6, 22, new EventObj());
      foreach (var entry in events_list.Flatten())
      {
          Console.WriteLine($"{entry.Year}.{entry.Month}.{entry.Day} {entry.Item}");
      }
      

      输出:

      2019.6.21 事件对象
      2019.6.22 EventObj
      2019.6.22 EventObj

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-26
        • 2018-09-13
        • 1970-01-01
        • 1970-01-01
        • 2021-02-05
        • 2019-01-11
        • 1970-01-01
        • 2018-10-10
        相关资源
        最近更新 更多