开发者

Custom Combining 4 dictionaries

I have 4 dictionaries of type

Dictionary<string,string>

dict1

k1 = v1
k2 = v2
k4 = v4

dict 2

k2 = vv2
k3 = v3


dict3
k2 = vvv2

dict 4

k4 = vvvv4

result dict of type Dictionary<string,List<string>>

k1 = v1,"","","" //combine 4 dict but put blan开发者_C百科k values in respective positions where values are not found
k2 = v2,vv2,vvv2,""
k3 = "",v3,"",""
k4 = v4,"","",vvvv4

Is this achievable? Any extension method??


I'm not convinced an extension method is the best design for this. Here is a standard method which will merge any number of dictionaries.

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

This is much more flexible, and readable, than the other LINQ solutions posted here.

Here's a LINQPad test you can use to verify:

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


Not inbuilt; but maybe something like:

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


Tested with 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();
}

You can combine the entire thing into just one Linq query:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜