2010-11-04 14 views
1

J'ai 4 dictionnaires de typemoissonnage 4 dictionnaires

Dictionary<string,string> 

dict1 

k1 = v1 
k2 = v2 
k4 = v4 

dict 2 

k2 = vv2 
k3 = v3 


dict3 
k2 = vvv2 

dict 4 

k4 = vvvv4 

résultat dict de type 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 

Est-ce réalisable? Toute méthode d'extension?

Répondre

1

Non intégré; mais peut-être quelque chose comme:

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

Testée avec 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(); 
} 

Vous pouvez combiner la chose entière en une seule requête 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

Je ne suis pas convaincu une méthode d'extension est le meilleur design pour cela. Voici une méthode standard qui va fusionner n'importe quel nombre de dictionnaires.

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; 
} 

Cela est beaucoup plus souple et lisible , que les autres solutions LINQ affichées ici.

est ici un test de LINQPad vous pouvez utiliser pour vérifier:

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