我想在我的Equals方法中比较几个集合的内容.我有一个词典和一个IList.有没有内置的方法来做到这一点?
编辑:我想比较两个字典和两个IList,所以我认为平等意味着什么是明确的 - 如果两个字典包含映射到相同值的相同键,那么它们是相等的.
Enumerable.SequenceEqual
通过使用指定的IEqualityComparer(T)比较它们的元素来确定两个序列是否相等.
您不能直接比较列表和字典,但可以将Dictionary中的值列表与列表进行比较
正如其他人所建议并注意到的那样,对SequenceEqual
订单敏感.要解决这个问题,您可以按键对字典进行排序(这是唯一的,因此排序总是稳定的)然后使用SequenceEqual
.以下表达式检查两个字典是否相等,无论其内部顺序如何:
dictionary1.OrderBy(kvp => kvp.Key).SequenceEqual(dictionary2.OrderBy(kvp => kvp.Key))
编辑:正如Jeppe Stig Nielsen指出的那样,某些物体IComparer
与它们不相容IEqualityComparer
,产生了不正确的结果.使用具有此类对象的键时,必须IComparer
为这些键指定正确的键.例如,使用字符串键(显示此问题),您必须执行以下操作才能获得正确的结果:
dictionary1.OrderBy(kvp => kvp.Key, StringComparer.Ordinal).SequenceEqual(dictionary2.OrderBy(kvp => kvp.Key, StringComparer.Ordinal))
除了提到的SequenceEqual,这
如果两个列表长度相等且它们的对应元素根据比较器进行比较,则为true
(可能是默认的比较器,即覆盖Equals()
)
值得一提的是,在.NET4有SetEquals的ISet
对象,
忽略元素和任何重复元素的顺序.
因此,如果您想要一个对象列表,但它们不需要按特定顺序排列,请考虑ISet
(如a HashSet
)可能是正确的选择.
看一下Enumerable.SequenceEqual 方法
var dictionary = new Dictionary() {{1, "a"}, {2, "b"}}; var intList = new List {1, 2}; var stringList = new List {"a", "b"}; var test1 = dictionary.Keys.SequenceEqual(intList); var test2 = dictionary.Values.SequenceEqual(stringList);
.NET缺乏用于比较集合的强大工具.我开发了一个简单的解决方案,您可以在以下链接中找到:
http://robertbouillon.com/2010/04/29/comparing-collections-in-net/
无论顺序如何,这都将执行相等比较:
var list1 = new[] { "Bill", "Bob", "Sally" }; var list2 = new[] { "Bob", "Bill", "Sally" }; bool isequal = list1.Compare(list2).IsSame;
这将检查是否添加/删除了项目:
var list1 = new[] { "Billy", "Bob" }; var list2 = new[] { "Bob", "Sally" }; var diff = list1.Compare(list2); var onlyinlist1 = diff.Removed; //Billy var onlyinlist2 = diff.Added; //Sally var inbothlists = diff.Equal; //Bob
这将看到字典中的哪些项目发生了变化:
var original = new Dictionary() { { 1, "a" }, { 2, "b" } }; var changed = new Dictionary () { { 1, "aaa" }, { 2, "b" } }; var diff = original.Compare(changed, (x, y) => x.Value == y.Value, (x, y) => x.Value == y.Value); foreach (var item in diff.Different) Console.Write("{0} changed to {1}", item.Key.Value, item.Value.Value); //Will output: a changed to aaa