簡體   English   中英

比較2列表 <Dictionary<string, object> &gt;

[英]Compare 2 List<Dictionary<string, object>>

我有一個函數,它返回一個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中的所有行都必須是。 確定刪除行比較或結果集進行迭代更加容易。

我的代碼工作,它只是看起來復雜和脆弱。

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));
}

嗯...你這樣做 我問的原因是這個超級有用的單元測試方法叫做CollectionAssert.AreEquivalent

從備注部分:

如果兩個集合具有相同數量的相同元素,則它們是等效的,但是以任何順序排列。 如果元素的值相等,則元素相等,而不是它們引用相同的對象。

看起來它完全符合您的要求,並且如果兩者不相等則拋出AssertFailedException,這也可能是您想要的。 有沒有辦法利用它? 一個方法調用肯定遠遠大於三重嵌套循環 - 即使這是方法所做的事情。

foreach(Dictionary<string, object> rowCompare in B)
    if(!A.Contains(rowCompare)) return false;
return true;

假設您的比較器設置正確,這將起作用。 並且簡單易懂。 如果您覺得這樣更容易,您甚至可以重新添加大括號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM