合并关键级别的字典,然后是价值级别

时间:2010-09-03 09:06:21

标签: c# linq dictionary

我有两个词典,比如

Dictionary<String, String> one = new Dictionary<string, string>
{
    { "A", "1" },
    { "B", "2" },
    { "C", "3" },
    { "D", "4" },
    { "E", "5" },
    { "F", "6" },
    { "G", "7" },
    { "H", "8" }
};

Dictionary<String, String> two = new Dictionary<string, string>
{
    { "A", "1" },
    { "B", "2" },
    { "C", "3" },
    { "E", "4" },
    { "F", "4" },
    { "I", "6" },
    { "J", "10" },
    { "K", "11" }
};

我需要在关键级别合并两个字典,然后在值级别合并并将结果字典添加到新字典three中,生成的字典不应该具有相同的键或相同的值,在这种情况下结果字典就像

Dictionary<String, String> three = new Dictionary<string, string>
{
    { "A", "1" },
    { "B", "2" },
    { "C", "3" },
    { "D", "4" },
    { "E", "5" },
    { "F", "6" },
    { "G", "7" },
    { "H", "8" },
    { "J", "10" },
    { "K", "11" }
};

现在我正在使用

  1. 联合两个词典中的所有键
  2. 使用新密钥创建新词典
  3. 删除重复值(相同值)
  4. 编辑:如果两个字典都具有相同的键值对,那么我需要存储第一个字典中的键值对。

    有没有办法用LINQ做到这一点? 提前致谢

4 个答案:

答案 0 :(得分:2)

一种选择,使用字典是一系列键/值对的事实:

var dictionary = dictionary1.Concat(dictionary2)
                            .ToLookup(pair => pair.Key, pair => pair.Value)
                            .ToDictionary(x => x.Key, x => x.First());

这不是非常有效,诚然(因为它本质上构建了一个哈希表两次)但我相信它会起作用。

答案 1 :(得分:1)

var three = new Dictionary<string, string>();
foreach(var kvp in two.Concat(one))
  three[kvp.Key] = kvp.Value;

这非常有效,但我不确定这是否是您想要的输出;问题陈述不够明确。

编辑:如果您希望随后从three删除重复的

var keysWithDuplicateValues = three.ToLookup(kvp => kvp.Value, kvp => kvp.Key)
                                   .SelectMany(group => group.Skip(1))
                                   .ToList();

foreach(var key in keysWithDuplicateValues)
   three.Remove(key);   

请注意,这比在开始时急切删除重复键重复值更好,因为某些冲突可能会自动解决。

答案 2 :(得分:1)

仅限linq的方法是连接两个字典并将结果的键/值序列折叠成单个结果。这将覆盖dict2中同样位于dict1

中的任何键的值
var dict3 = dict2.Concat(dict1)
    .Aggregate(new Dictionary<string, string>(), (d, kvp) => {
        d[kvp.Key] = kvp.Value;
        return d;
    });

答案 3 :(得分:1)

class StringKeyValuePairEqualityComparer : IEqualityComparer<KeyValuePair<string, string>>
{
    public bool Equals(KeyValuePair<string, string> x, KeyValuePair<string, string> y)
    {
        return x.Key == y.Key;
    }

    public int GetHashCode(KeyValuePair<string, string> obj)
    {
        return obj.Key.GetHashCode();
    }
}

var three = Enumerable.Concat(one, two)
                .Distinct(new StringKeyValuePairEqualityComparer())
                .ToDictionary(p => p.Key, p => p.Value);

int count = three.Keys.Count; // 11