繁体   English   中英

比较两个字典并返回差额

[英]Compare Two Dictionaries and Return the Difference

我有两个字典,一个包含原始数据,另一个包含新数据。 我想比较两个字典并返回一个字典,然后返回包含更新的第三个字典。

Dictionary<int, Dictionary<string, string>> OriginalDictionary = new Dictionary
{
    {1, new Dictionary<string, string> 
        {{"name", "adam"}, 
         {"age", "15"}
         {"occupation", "student"}},
    {2, new Dictionary<string, string> 
        {{"name", "bob"}, 
         {"age", "40"}
         {"occupation", "doctor"}},
    {3, new Dictionary<string, string> 
        {{"name", "cameron"}, 
         {"age", "32"}
         {"occupation", "teacher"}},
}

Dictionary<int, Dictionary<string, string>> NewDictionary = new Dictionary
{
    {1, new Dictionary<string, string> 
        {{"name", "adam"}, 
         {"age", "15"}
         {"occupation", "student"}},
    {2, new Dictionary<string, string> 
        {{"name", "bob"}, 
         {"age", "40"}
         {"occupation", "lawyer"}}, //this is where it's different
    {3, new Dictionary<string, string> 
        {{"name", "cameron"}, 
         {"age", "32"}
         {"occupation", "teacher"}},
}

我想获得包含更新的第三本词典。 它可以是整个第一级,也可以分解为第二级。 下面的两个示例对我都适用。

Dictionary<int, Dictionary<string, string>> UpdateDictionary1 = new Dictionary
{
    {2, new Dictionary<string, string> 
        {{"name", "bob"}, 
         {"age", "40"}
         {"occupation", "lawyer"}} //this is where it's different
}

Dictionary<int, Dictionary<string, string>> UpdateDictionary2 = new Dictionary
{
    {2, new Dictionary<string, string> 
        {{"occupation", "lawyer"}}
}

我已经尝试过这篇文章“ 如何在C#中比较两个词典”的答案,但是我为UpdateDictionary获得的结果仍然包含NewDictionary的所有数据。 UpdatesDictionary.Count == 3 ,我的预期输出应该是UpdatesDictionary.Count == 1 我尝试了Where答案和Except答案,但它们都没有按我希望的那样工作。

UpdateDictionary = OriginalDictionary.Where(entry => NewDictionary[entry.Key] != entry.Value).ToDictionary(entry => entry.Key, entry => entry.Value);

UpdateDictionary = OriginalDictionary.Except(NewDictionary).ToDictionary(x => x.Key, x => x.Value);

我还有其他方法可以解决这个问题吗?

谢谢!

所以首先是简单的部分。 查找添加或删除的密钥:

var addedKeys = NewDictionary.Keys.Except(OriginalDictionary.Keys);
var removedKeys = OriginalDictionary.Keys.Except(NewDictionary.Keys);

接下来,要查找具有已编辑字典的键,我们将为字典创建一个相等比较器,仅仅是因为尝试内联它们可能会产生差异的所有可能方式会太多。

public class DictionaryComparer<TKey, TValue> :
    IEqualityComparer<Dictionary<TKey, TValue>>
{
    private IEqualityComparer<TValue> valueComparer;
    public DictionaryComparer(IEqualityComparer<TValue> valueComparer = null)
    {
        this.valueComparer = valueComparer ?? EqualityComparer<TValue>.Default;
    }
    public bool Equals(Dictionary<TKey, TValue> x, Dictionary<TKey, TValue> y)
    {
        if (x.Count != y.Count)
            return false;
        if (x.Keys.Except(y.Keys).Any())
            return false;
        if (y.Keys.Except(x.Keys).Any())
            return false;
        foreach (var pair in x)
            if (!valueComparer.Equals(pair.Value, y[pair.Key]))
                return false;
        return true;
    }

    public int GetHashCode(Dictionary<TKey, TValue> obj)
    {
        throw new NotImplementedException();
    }
}

现在我们有了这个,调用它非常简单:

var addedKeys = NewDictionary.Keys.Except(OriginalDictionary.Keys);
var removedKeys = OriginalDictionary.Keys.Except(NewDictionary.Keys);
var comparer = new DictionaryComparer<string, string>();
var editedValues = OriginalDictionary.Where(pair =>
    !comparer.Equals(pair.Value, NewDictionary[pair.Key]));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM