我有一个返回List<Dictionary<string, object>>
的函数,其中object是标准类型(string,int等)。
我需要花一秒List<Dictionary<string, object>>
并确保列表B中的所有条目都在列表A中表示(列表中的顺序无关紧要)。
目前我的代码如下所示:
foreach(Dictionary<string, object> rowResult in A) {
foreach(Dictionary<string, object> rowCompare in B) {
foreach(string columnName in rowResult.Keys) {
// ... logic to compare columns
}
}
// ...logic to compare rows so we dont find the same row twice.
}
有更简单的方法吗?
我们不关心rowResult中的所有行,但rowCompare中的所有行都必须是。 可以从比较或结果集中删除行,以使迭代更容易。
我的代码有效,它只是看起来过于复杂和脆弱。
答案 0 :(得分:6)
class DictionaryComparer<TKey, TValue> : IEqualityComparer<Dictionary<TKey, TValue>> {
public bool Equals(Dictionary<TKey, TValue> x, Dictionary<TKey, TValue> y) {
if (x == null) {
throw new ArgumentNullException("x");
}
if (y == null) {
throw new ArgumentNullException("y");
}
if (x.Count != y.Count) {
return false;
}
foreach (var kvp in x) {
TValue value;
if(!y.TryGetValue(kvp.Key, out value)) {
return false;
}
if(!kvp.Value.Equals(value)) {
return false;
}
}
return true;
}
public int GetHashCode(Dictionary<TKey, TValue> obj) {
if (obj == null) {
throw new ArgumentNullException("obj");
}
int hash = 0;
foreach (var kvp in obj) {
hash = hash ^ kvp.Key.GetHashCode() ^ kvp.Value.GetHashCode();
}
return hash;
}
}
然后:
public bool Contains(
List<Dictionary<string, object>> first,
List<Dictionary<string, object>> second) {
if(first == null) {
throw new ArgumentNullException("first");
}
if(second == null) {
throw new ArgumentNullException("second");
}
IEqualityComparer<Dictionary<string, object>> comparer = new DictionaryComparer<string, object>();
return second.All(y => first.Contains(y, comparer));
}
答案 1 :(得分:2)
嗯......你在做什么 for ?我问的原因是这个超级有用的单元测试方法称为CollectionAssert.AreEquivalent。
来自备注部分:
如果两个集合具有相同数量的相同元素,则它们是等效的,但是以任何顺序排列。如果元素的值相等,则元素相等,而不是它们引用相同的对象。
看起来它完全符合您的要求,如果两者不相等,则抛出AssertFailedException,这也可能是您想要的。有没有办法利用它?一个方法调用肯定远远大于三重嵌套循环 - 即使这是方法所做的事情。
答案 2 :(得分:1)
foreach(Dictionary<string, object> rowCompare in B)
if(!A.Contains(rowCompare)) return false;
return true;
假设您的比较器设置得当,这将有效。并且简单易懂。如果你发现它更容易,你甚至可以重新添加大括号。