【问题标题】:Compare two List<Dictionary<string, string>> in C# and get result ListC#中比较两个List<Dictionary<string, string>>得到结果List
【发布时间】:2021-01-12 00:13:33
【问题描述】:

我想知道使用 lambda linq 和 C# 来获得两个 List&lt;Dictionary&lt;string, string&gt;&gt; 之间差异的更好解决方案是什么。

我正在尝试使用这样的表达式,但即使两个列表相同,也会得到一个空结果

var result = actualOutputList.Where(a => expectedOutputList.
            Any(e => (e.Values == a.Values) && (e.Keys == a.Keys))).ToList();

如果我改为!expectedOutputList 而不是expectedOutputList,即使存在差异,我也会得到完整的结果列表。

应该如何比较两个List&lt;Dictionary&lt;string, string&gt;&gt; 并获得正确的结果列表?

【问题讨论】:

  • 呃,为什么需要字典列表?你能不能只有一本字典?
  • C# 是关于类型的:e.Values 的类型是什么? operator== 对这种类型有什么作用?你希望发生什么?
  • 在这种情况下,“获取差异”是什么意思?您是否期望actualOutputList 成员不在expectedOutputList 成员中?您是否期望expectedOutputList 成员不在actualOutputList 成员中?你期待两者吗?
  • 请注意,通常比较 DictionaryValuesDictionaryKeys 并没有说明字典的等价性:键和值之间的映射可能完全不同。

标签: c# list linq lambda


【解决方案1】:

您可以为Dictionary 创建一个IEqualityComparer 子类:

public class DictionaryEqualityComparer<TKey, TValue> : IEqualityComparer<Dictionary<TKey, TValue>> {
    public bool Equals(Dictionary<TKey, TValue> d1, Dictionary<TKey, TValue> d2) {
        if (ReferenceEquals(d1, d2))
            return true;

        if (d1.Keys.Count != d2.Keys.Count)
            return false;

        foreach (var kvp in d1) {
            if (d2.TryGetValue(kvp.Key, out TValue val)) {
                if (!kvp.Value.Equals(val))
                    return false;
            }
            else
                return false;
        }

        return true;
    }

    public int GetHashCode(Dictionary<TKey, TValue> d) {
        var hc = new HashCode();
        foreach (var kvp in d.OrderBy(kvp => kvp.Key)) {
            hc.Add(kvp.Key);
            hc.Add(kvp.Value);
        }
        return hc.ToHashCode();
    }
}

然后你可以用它和 LINQ 来得到你的答案:

var de = new DictionaryEqualityComparer<string,string>();
var result = expectedOutputList.Except(actualOutputList, de);

这将返回 actualOutputList 中缺少的字典 - 如果您还想要任何额外的字典,则需要:

var result2 = expectedOutputList.Except(actualOutputList, de)
                                .Concat(actualOutputList.Except(expectedOutputList, de));

【讨论】:

    【解决方案2】:

    另外,您确定需要比较字典列表吗??

    如果您可以在 INPUT 和预期的 OUTPUT 示例中给我们提供说明您期望发生的事情,那就太好了。

    下面将只返回a 的键,因为这是两个字典中唯一匹配的键。如果您更改键 b 的值以匹配,则将返回两个键/值对作为结果。

    
    var myDict = new Dictionary<string, string>
            {
                { "a", "c" },
                { "b", "d" }
            };
    
                var otherDict = new Dictionary<string, string>
            {
                { "a", "c" },
                { "b", "e" }
            };
    
                var result = myDict.Where(x => otherDict.Any(t => t.Key == x.Key && t.Value == x.Value)).ToList();
               
    
    

    【讨论】:

      猜你喜欢
      • 2014-12-03
      • 2017-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-20
      • 1970-01-01
      • 2018-08-04
      • 2020-01-26
      相关资源
      最近更新 更多