在C#中使用LINQ比较和合并字典

时间:2010-08-02 04:58:28

标签: c# linq

我有两个词典,比如

  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"

我需要比较和合并两个dictonaries而不管键和将数据添加到第三个字典

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中的First列表,然后搜索列表中的项目是否存在于DictTwo的任何列表中,如果这样执行union操作,然后使用任意一个键将结果列表添加到第三个字典中(键入DictOne或DictTwo)如果列表不存在,则将列表与键一起添加到第三个词典中。同样适用于DictOne和DictTwo中的所有列表

有没有办法使用LINQ

来做到这一点

提前致谢

4 个答案:

答案 0 :(得分:2)

呼!相当挑战。基本上,它们是字典的事实是完全无关紧要的,你只需要每个字典的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的协方差支持。

答案 1 :(得分:-1)

你可以这样做:

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

或者,如果您需要将其保留为词典:

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

答案 2 :(得分:-1)

您可以使用此方法:

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

当然,如果你想使用你自己的相等比较,你可以将IEqualityComparer作为第二个参数提供给GroupBy方法。

答案 3 :(得分:-1)

如果您想要的是,按键合并每个列表的所有条目,您可以这样做:

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());

这将在每个键的每个列表中产生不同的字符串。