2010-11-04 71 views
1

我有4个字典类型的类型自定义组合4个词典

Dictionary<string,string> 

dict1 

k1 = v1 
k2 = v2 
k4 = v4 

dict 2 

k2 = vv2 
k3 = v3 


dict3 
k2 = vvv2 

dict 4 

k4 = vvvv4 

结果字典Dictionary<string,List<string>>

k1 = v1,"","","" //combine 4 dict but put blank values in respective positions where values are not found 
k2 = v2,vv2,vvv2,"" 
k3 = "",v3,"","" 
k4 = v4,"","",vvvv4 

这是可以实现的?任何扩展方法?

回答

1

没有内置;但也许是这样的:

var keys = dict1.Keys.Union(dict2.Keys).Union(dict3.Keys).Union(dict4.Keys); 
var result = new Dictionary<string,List<string>>(); 
foreach(var key in keys) { 
    List<string> list = new List<string>(); 
    list.Add(dict1.ContainsKey(key) ? dict1[key] : ""); 
    list.Add(dict2.ContainsKey(key) ? dict2[key] : ""); 
    list.Add(dict3.ContainsKey(key) ? dict3[key] : ""); 
    list.Add(dict4.ContainsKey(key) ? dict4[key] : ""); 
    result.Add(key, list); 
} 
1

测试了LINQPad

void Main() 
{ 
    var dict1 = new Dictionary<string, string> 
    { 
     { "k1", "v1" }, 
     { "k2", "v2" }, 
     { "k4", "v4" }, 
    }; 
    var dict2 = new Dictionary<string, string> 
    { 
     { "k2", "vv2" }, 
     { "k3", "v3" }, 
    }; 
    var dict3 = new Dictionary<string, string> 
    { 
     { "k2", "vvv2" }, 
    }; 
    var dict4 = new Dictionary<string, string> 
    { 
     { "k4", "vvvv4" }, 
    }; 

    var keys = dict1.Keys 
     .Union(dict2.Keys) 
     .Union(dict3.Keys) 
     .Union(dict4.Keys); 
    var table = 
     from key in keys 
     let v1 = dict1.ContainsKey(key) ? dict1[key] : "" 
     let v2 = dict2.ContainsKey(key) ? dict2[key] : "" 
     let v3 = dict3.ContainsKey(key) ? dict3[key] : "" 
     let v4 = dict4.ContainsKey(key) ? dict4[key] : "" 
     select new { key, values = new List<string> { v1, v2, v3, v4 } }; 
    var result = table 
     .ToDictionary(r => r.key, r => r.values); 
    result.Dump(); 
} 

你可以把整个东西结合成只有一个Linq查询:

var result = 
    (from key in dict1.Keys.Union(dict2.Keys).Union(dict3.Keys).Union(dict4.Keys) 
    let v1 = dict1.ContainsKey(key) ? dict1[key] : "" 
    let v2 = dict2.ContainsKey(key) ? dict2[key] : "" 
    let v3 = dict3.ContainsKey(key) ? dict3[key] : "" 
    let v4 = dict4.ContainsKey(key) ? dict4[key] : "" 
    select new { key, values = new List<string> { v1, v2, v3, v4 } }) 
    .ToDictionary(r => r.key, r => r.values); 
4

我不相信一个扩展方法是最好的设计。这是一个标准方法,它将合并任意数字字典的

Dictionary<string,List<string>> Merge(params Dictionary<string,string>[] dicts) 
{ 
    var target = new Dictionary<string, List<string>>(); 
    var allKeys = dicts.SelectMany(d => d.Keys).Distinct(); 

    foreach(var key in allKeys) 
    { 
     foreach(var dict in dicts) 
     { 
      if(target.ContainsKey(key)) 
      { 
       target[key].Add(dict.ContainsKey(key) ? dict[key] : ""); 
      } 
      else 
      { 
       target[key] = new[] {dict.ContainsKey(key) ? dict[key] : ""} .ToList(); 
      } 
     } 
    } 

    return target; 
} 

这是更为灵活,可读,比其他解决方案LINQ张贴在这里。

这里有一个LINQPad测试,你可以用它来验证:

var d1 = new Dictionary<string,string> { {"k1","v1"}, {"k2","v2"}, {"k4","v4"} } ; 
var d2 = new Dictionary<string,string> { {"k2","vv2"}, {"k3","v3"} } ; 
var d3 = new Dictionary<string,string> { {"k2","vvv2"} } ; 
var d4 = new Dictionary<string,string> { {"k4","vvvv4"} } ; 

Merge(d1,d2,d3,d4).Dump();