2010-08-02 160 views
2

我有两个字典一样比较和合并字典

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" 

现在,我通过两个dictionar迭代IES

现在,我使用像

首先我要在DictOne第一个列表,然后在搜索列表中的项目是否存在于DictTwo任何列表中,如果这样进行合并操作,然后添加使用任何一个键(键入DictOne或DictTwo)将结果列表放入第三个词典中。如果列表不存在,则将该列表与键一起添加到第三个词典中。同样将在DictOne而DictTwo

所有列表执行有没有办法做到这一点使用LINQ提前

感谢

回答

2

Whe!相当大的挑战。基本上,他们是字典这一事实是完全不相关的,你只需要每个字典的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的协方差支持。

+0

我不知道为什么这个答案被否决,因为它实际上似乎正确回答了这个有点不明确的问题。 – 2010-08-02 11:47:11

+0

更有趣的是,这个问题在四个不同的答案上有不少于4个的降低评分,没有任何一个解释原因的评论。 – 2010-08-02 11:52:01

+0

@ Allon Guralnek:所有的答案都只是简单的说明你的两本词典。 而在你的回答中,IEnumerable 无法转换为 IEnumerable > – 2010-08-02 12:01:15

-1

你可以这样做:

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

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

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

您可以使用此认可CH:

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

当然,如果你想使用自己的平等的比较,就可以起到的IEqualityComparer到的GroupBy方法,第二个参数。

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

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

+0

这只是concatinating这两个字典。我需要基于价值而不是密钥 – 2010-08-02 12:04:37

+0

进行协调那么,这个问题有点含糊不清,不是吗? ;-) – 2010-08-02 12:16:38