加入或合并两个词典,其中相同的键产生联合值

时间:2015-07-24 17:33:24

标签: c# linq dictionary enums

我正在使用此链接中的答案Linq join two dictionaries using a common key

产生我想要的结果。不幸的是,我不确定如何将结果转换回字典对象,因为结果是某种类型的System.Linq.Enumerable + WhereSelectEnumerableIterator,我不知道如何处理它。

好的,细节。 假设我有以下内容:

Dictionary<string, People> result =  new Dictionary<string, People>() { 
    { "athletes", People.Adam | People.Barry | People.Chris | People.Harold }, 
    { "artists", People.Frank | People.Harold | People.Eric } };

当我在调试器中查看结果时,我看到“结果视图”几乎具有我想要的结果。它看起来像是用一个Key创建了两个词典。现在我仔细查看了查询,这正是它的作用。

这就是我想要的结果:

var result

即使我能够从select查询中获取var x = function() { }; 我想要的内容,我也不确定如何访问该数据,因为它不是Dictionary对象。 (我可以轻松使用Andrew Orsich在此提供的精彩合并扩展:Merging dictionaries in C#

2 个答案:

答案 0 :(得分:1)

结果之后你想要这样的东西吗?

        var finalDic = new Dictionary<string, People>();

        foreach (var dic in result) {
            foreach (var key in dic.Keys) {
                People people;
                if (finalDic.TryGetValue(key, out people)) {
                    finalDic[key] = people | dic[key];  
                }
                else {
                    finalDic[key] = dic[key];
                }                   
            }
        }

//输出

运动员:Adam,Barry,Chris,Harold

艺术家:Eric,Frank,Harold

但你可以简单地将第一本字典作为初始对象,并使用第二种字典做我上面的类似的事情:

        var EUxUSInterest = new Dictionary<string, People>(EUInterest);

        foreach (var element in USInterest) {
            People people;
            if (EUxUSInterest.TryGetValue(element.Key, out people)) {
                EUxUSInterest[element.Key] = people | element.Value;    
            }
            else {
                EUxUSInterest[element.Key] = element.Value;
            }   
        }

//输出相同

运动员:Adam,Barry,Chris,Harold

艺术家:Eric,Frank,Harold

答案 1 :(得分:0)

嗯,这可能不是最有效的方法(我会查看HashSet的想法)。关于查询的问题的答案是我应该在foreach循环中使用它。我试图通过访问某些属性来使用该查询。

此答案使用上述问题中提到的MergeLeft Dictionary扩展名。

[Flags]
enum People
{
    None = 0x0, Adam = 0x1, Barry = 0x2, Chris = 0x4, David = 0x8, 
    Eric = 0x10, Frank = 0x20, George = 0x40, Harold = 0x80, Ian = 0x100, 
    Joe = 0x200, Larry = 0x400, Mark = 0x800, Nathan = 0x1000, Oscar = 0x2000, 
    Paul = 0x4000, Roger = 0x8000, Sam = 0x10000, Tom = 0x20000, 
    Victor = 0x40000, Walter = 0x80000,Yogi = 0x100000, Zane = 0x200000
};

Dictionary<string, People> EUInterest = new Dictionary<string, People>() { 
{ "athletes", People.Adam | People.Barry }, 
{ "artists", People.Frank | People.Harold } };
Dictionary<string, People> USInterest = new Dictionary<string, People>() { 
{ "athletes", People.Chris | People.Harold }, 
{ "artists", People.Eric } };

var query = from interest in EUInterest.Keys
                where USInterest.ContainsKey(interest)
                let v1 = EUInterest[interest]
                let v2 = USInterest[interest]
                select new Dictionary<string, People>() { {interest, v1 | v2 } };

Dictionary<string, People> temp = new Dictionary<string, People>();
foreach (var a in query)
{
    temp = temp.MergeLeft(a);
}

foreach (People option in Enum.GetValues(typeof(People)))
{
    if (temp["athletes"].HasFlag(option))
        Console.WriteLine("{0} IS AN ATHLETE.", option);
    // else Console.WriteLine("{0} is not an athlete.", option);
}