代码之家  ›  专栏  ›  技术社区  ›  Thorin Oakenshield

在C语言中使用LINQ比较和合并词典#

  •  2
  • Thorin Oakenshield  · 技术社区  · 14 年前

      Dictionary<String,List<String>> DictOne=new Dictionary<String,List<String>>()
      Dictionary<String,List<String>> DictTwo=new Dictionary<String,List<String>>()
    
     DictOne
    
    
    KeyOne     "A"
               "B"
    
    KeyTwo     "C"
               "D"
    
    KeyThree   "X"
               "Y"
    
    
    
    DictTwo
    
    Key1      "X"
              "Z"
              "Y"
    
    Key2      "A"
    
    
    Key3     "C"
             "D"
    
    Key4     "M"
             "N"
    

    Dictionary<String,List<String>> DictThree=new Dictionary<String,List<String>>()
    

    DictThree
    
    KeyOne   "A"
             "B"
    
    KeyTwo   "C"
             "D"
    
    KeyThree "X"
             "Y"
             "Z"
    
    Key4     "M"
             "N"
    

    现在我反复阅读这两本词典

    现在我用的是

    首先,我将获取DictOne中的第一个列表,然后搜索列表中的项目是否存在于DictTwo中的任何列表中(如果存在),执行并集操作,然后使用任意一个键(DictOne中的键或DictTwo中的键)将结果列表添加到第三个字典中。如果列表不存在,则将列表连同键添加到第三个字典中。对于DictOne和DictTwo中的所有列表都将执行相同的操作

    使用LINQ有什么方法可以做到这一点吗

    提前谢谢

    4 回复  |  直到 14 年前
        1
  •  2
  •   Allon Guralnek    14 年前

    呼!相当大的挑战。基本上,它们是字典这一事实是完全不相关的,你只需要 Dictionary<,>.Values string[][] )对于这个例子。

    var group1 = new string[][] { new[] { "A", "B" }, new[] { "C", "D" }, new[] { "X", "Y" } };
    var group2 = new string[][] { new[] { "X", "Y", "Z" }, new[] { "A" }, new[] { "C", "D" }, new[] { "M", "N" } };
    
    // For each array in group1, check if it has matching array in group2, if
    // it does, merge, otherwise just take the array as is.
    var group1Join = from g1 in group1
                     let match = group2.SingleOrDefault(g2 => g1.Intersect(g2).Any())
                     select match != null ? g1.Union(match) : g1;
    
    // Take all the group2 arrays that don't have a matching array in group1 and
    // thus were ignored in the first query.
    var group2Leftovers = from IEnumerable<string> g2 in group2
                          where !group1.Any(g1 => g2.Intersect(g1).Any())
                          select g2;
    
    var all = group1Join.Concat(group2Leftovers);
    

    编辑:修正代码在C#3.0中工作,不依赖C#4.0的协方差支持。

        2
  •  -1
  •   snurre    14 年前

    您可以这样做:

    Dictionary<String, List<String>> DictThree = DictOne.Concat(DictTwo);
    

    或者,如果你需要把它作为一本字典:

    Dictionary<String, List<String>> DictThree = DictOne.Concat(DictTwo).ToDictionary(x => x.Key);
    
        3
  •  -1
  •   Martin JonáÅ¡    14 年前

    您可以使用以下方法:

    var dict3 = DictOne
        .Concat(DictTwo)
        .GroupBy(x => x.Key)
        .ToDictionary(x => x.Key, x => x.SelectMany(y => y.Value).ToList());
    

        4
  •  -1
  •   Robert Giesecke    14 年前

    如果您希望按键合并每个列表的所有条目,可以按如下方式进行:

    var dictThree = (from kv in dictOne.Concat(dictTwo)
                      group kv.Value by kv.Key)
       .ToDictionary(k => k.Key, v => v.SelectMany(l => l).Distinct().ToList());