我能否比较两个字典的键?

15

我想使用C#比较两个字典,具体地说是两个具有相同键但不同值的字典,我找到了一个方法Comparer,但我不太确定如何使用它?除了逐个迭代每个键之外,还有其他方法吗?

Dictionary
[
    {key : value}
]

Dictionary1
[
    {key : value2}
]

4
你想要实现什么目标并不确定... 你是想找出在Dictionary1中而不在dictionary2中的键吗?还是找出两者中都有但其值不同的键? - Yahia
7个回答

27

如果你只想知道两个字典的键是否不同,而不需要知道具体是哪些键不同,可以使用Keys属性上的SequenceEqual扩展方法:

Dictionary<string,string> dictionary1;
Dictionary<string,string> dictionary2;
var same = dictionary1.Count == dictionary2.Count && dictionary1.Keys.SequenceEqual(dictionary2.Keys);

如果您想要实际的区别,可以像这样:

var keysDictionary1HasThat2DoesNot = dictionary1.Keys.Except(dictionary2.Keys);
var keysDictionary2HasThat1DoesNot = dictionary2.Keys.Except(dictionary1.Keys);

7
a) 因为SequenceEqual已经做了比较计数的工作,所以计数比较是多余的。 b) SequenceEqual不能用于字典,因为它要求键按相同顺序排列。在某些情况下可能有效,但如果键已添加或删除,则会失败。 - Jim Balter
字典的 Keys 方法不保留键的顺序。这样做行不通。 - Yair Halberstadt

9
return dict1.Count == dict2.Count && 
       dict1.Keys.All(dict2.ContainsKey);

欢迎来到 Stack Overflow!如果您能在回答中添加一些解释,那将非常有帮助。 - krsteeve

1

试试这个

public bool SameKeys<TKey, TValue>(IDictionary<TKey, TValue> one, IDictionary<TKey, TValue> two)
{
    if (one.Count != two.Count) 
        return false;
    foreach (var key in one.Keys)
    {
        if (!two.ContainsKey(key))
            return false;
    }
    return true;
}

我认为你的 if 语句应该是 one.Count != two.Count - vcsjones

0

如果有帮助的话,您可以获取键的集合并对其进行索引。

dictionary1.keys[0] == dictionary2.keys[5]

我其实不确定你是用数字还是用键本身来索引它,所以两种方式都试一下。


1
它们用数字进行索引,但是“Keys”需要大写字母。此外,这将需要迭代每个键,这是他想要避免的事情。 - Tipx

0
你可以根据需要选择以下方案(取交集或排除):
Dictionary<int, int> dict1 = new Dictionary<int, int>();
Dictionary<int, int> dict2 = new Dictionary<int, int>();

IEnumerable<int> keys1ExceptKeys2 = dict1.Keys.Except(dict2.Keys);
IEnumerable<int> keys2ExceptKeys1 = dict2.Keys.Except(dict1.Keys);
IEnumerable<int> keysIntersect = dict1.Keys.Intersect(dict2.Keys);

0

你可以这样做:

new HashSet<TKey>(dictionary1.Keys).SetEquals(dictionary2.Keys)

如果dictionary1使用与dictionary2不同的比较器,请小心处理。您需要决定“相等”意味着什么,是由其中一个字典所认为的,还是其他完全不同的含义...


0
我认为这是除了计数之外检查键之间差异的最快方法。
var isTrue = !dict1.Keys.Any(k => !dict2.Keys.Contains(k)) &&
                         !dict2.Keys.Any(k => !dict1.Keys.Contains(k));

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