比较两个字典(键,值),返回值不相同的键。

7

我对C#还不太熟悉,想要识别在比较两个字典时,没有相同值的键。

我所拥有的字典是 dict => KeyValuePair<string, string> 类型的。我有两个字典,如下所示:

dict1 => {"a":"False","b":"amazonaws.com","c":"True"}
dict2 => {"a":"True","b":"amazonaws.com","c":"False"}

我希望能够比较两个字典并返回一个变量,该变量将具有键["a","c"],就像上面的示例一样,这些键具有不同的值。
目前我编写的逻辑只会区分另一个字典中不存在的键。
Dictionary dictExcept = null;
foreach (IDictionary kvp in dict1.Cast<object>().Where(kvp => !dict2.Contains(kvp)))
    {
        dictExcept.Add(kvp.Keys, kvp.Values);
    }
return dictExcept ;

循环遍历dict1.Keys,对于每个键检查if(dict1[key] != dict2[key]) keyList.Add(key);。假设两个字典中的键都是字符串类型,keyList是一个List<string> - Chetan
我们可以假设两个字典包含完全相同的键(或者你只对这些感兴趣);还是你也想考虑存在于一个字典中但不存在于另一个字典中的键? - Flater
@Flater 两个字典将具有相同的键,只是我们需要识别具有不同值的键。 - Biswajit Maharana
不要忘记实例化dictExcept,因为否则会抛出异常:“dictExcept.Add”。 - EKOlog
3个回答

1
您可以尝试使用“TryGetValue”方法(点此查看):
using System.Linq;

...

var dictExcept = dict1
  .Where(pair => dict2.TryGetValue(pair.Key, out var value) && 
                 pair.Value != value)
  .ToDictionary(pair => pair.Key, 
                pair => (first: pair.Value, second: dict2[pair.Key]));

在这里,我们针对来自dict1的每个键值对,尝试从dict2中获取相应的value

// dict2 has pair.Key it corresponds to value...
dict2.TryGetValue(pair.Key, out var value) && 
// however value from dict2 != value from dict1
pair.Value != value

如果您喜欢使用foreach(没有Linq解决方案),可以采用同样的想法:

var dictExcept = new Dictionary<string, (string first, string second)>();

foreach (var pair in dict1)
  if (dict2.TryGetValue(pair.Key, out var value) && value != pair.Value)
    dictExcept.Add(pair.Key, (pair.Value, value)); 

Demo: (fiddle)

  var dict1 = new Dictionary<string, string> { 
    { "a", "False" }, { "b", "False" }, { "c", "True" }, { "d", "dict1 only" } };

  var dict2 = new Dictionary<string, string> { 
    { "a", "False" }, { "b", "True" }, { "c", "False" }, { "e", "dict2 only" } };

  var dictExcept = dict1
    .Where(pair => dict2.TryGetValue(pair.Key, out var value) &&
                   pair.Value != value)
    .ToDictionary(pair => pair.Key,
                  pair => (first: pair.Value, second: dict2[pair.Key]));

  string report = string.Join(Environment.NewLine, dictExcept
    .Select(pair => $"Key: {pair.Key}; Values: {pair.Value}"));

  Console.Write(report);

结果:

Key: b; Values: (False, True)
Key: c; Values: (True, False)

0

既然你有一个名为dictExcept的字典,那么使用Expect来为你完成这项工作如何?

生成两个序列的差集。

源代码

在你的情况下:

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    static void Main(string[] args)
    {
        var a = new Dictionary<string, string>{{"a", "False"}, {"b", "False"}, {"c", "True"}};
        var b = new Dictionary<string, string>{{"a", "False"}, {"b", "True"}, {"c", "False"}};
        
        var c = a.Except(b).Select(x => x.Key);
        c.Dump();
    }
}

输出

[ b, c ]

在线试用!

更多不同情况的示例:

static void Main(string[] args)
{
    var a = new Dictionary<string, string>{{"a", "False"}, {"b", "False"}, {"c", "True"}};
    var b = new Dictionary<string, string>{{"a", "False"}, {"b", "True"}, {"c", "False"}};
    
    var c = a.Except(b).Select(x => x.Key);
    // c is [ b ,c ]
    
    a.Add("d", "foo");
    
    var d = a.Except(b).Select(x => x.Key);
    // d is [ b, c, d ]
    
    b.Add("e", "foo");
    
    var e = a.Except(b).Select(x => x.Key);
    // e is still [ b, c, d ]
    
    var e2 = (a.Except(b)).Union(b.Except(a)).Select(x => x.Key).Distinct();
    // e is [ b, c, d, e ]
}

在线尝试!


0
提供最简单的答案,基于您的评论:
两个字典将拥有相同的键,只需要识别具有不同值的键即可。
在假设您不需要考虑缺失键的情况下,您可以简单地迭代其中一个字典的所有键,并比较在该键下找到的值。
var keysWithDifferentValues = new List<string>();

foreach (var kvp in dict1)
{
    if(!kvp.Value.Equals(dict2[kvp.Key]))
        keysWithDifferentValues.Add(kvp.Key);
}

使用LINQ可以简化此操作:

var keysWithDifferentValues = 
      dict1
        .Where(kvp => !kvp.Value.Equals(dict2[kvp.Key]))  
        .Select(kvp => kvp.Key)
        .ToList();                                  

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接