【问题标题】:Compare 2 List<Dictionary<string,object>> in c#在 c# 中比较 2 List<Dictionary<string,object>>
【发布时间】:2017-09-07 14:21:44
【问题描述】:

我有 2 个字典列表

List<Dictionary<string,object>> master
List<Dictionary<string,object>> sub

我的两个字典都有相同的键名。

EX: The first list Master contains
Master.Add(new Dictionary<string, string>(){

{"key1","SAME1"}
{"key2", "value1"},
{"key3","value2"}
});
Master.Add(new Dictionary<string, string>(){
{"key1","SAME2"}
{"key2", "value3"},
{"key3","value5"}
});

Master.Add(new Dictionary<string, string>(){
{"key1","SAME77"}
{"key2", "value55"},
{"key3","value44"}
});

The second list sub contains similar kind of key,value pairing :

sub.Add(new Dictionary<string, string>(){
{"key1","SAME1"}
{"key2", "value7"},
{"key3","value9"}
});

Master.Add(new Dictionary<string, string>(){
{"key1","SAME2"}
{"key2", "value3"},
{"key3","value4"}
});

在 LinQ 中是否有一种方法(或任何其他更简单的方法)我可以用来比较 2 个字典列表并获得输出字典。示例

场景 1: 如您所见,我可以使用第一个字典列表中的一个键(Key1,因为它对所有人来说都是相同的值)来查看该值是否存在于第二个字典中,如果它不存在,我希望缺少的字典在新列表> .

Output Ex: NewList.Add(new Dictionary<string, string>(){
{"key1","SAME77"} // since SAME77 isn't present in sub dictionary 
{"key2", "value55"},
{"key3","value44"}
}

场景 2: 如果假设字典子列表中的一个字典包含 key1 的相同值,我想检查同一字典的其他值,以及这些键的任何值是否已更改,如果它们有我想要一个新的 有原始的列表。

ex 输出:

NewList.Add(new Dictionary<string, string>(){
{"key1","SAME2"}
{"key2", "value3"},
{"key3","value5"} // since the master dictionary has value5 and the sublist dictionary has value 4 

}

场景 1 尝试:

var result = Master.SelectMany(m=>m).Where(e=>sub.SelectMany(a=>a)
                .Any(p => e.Key == p.Key && p.Value!=null && e.Value!=(p.Value)));

但是,这不会返回正确的结果,并且输出是 IEnumerable。有没有我可以通过 linq 本身获得所需的输出?

感谢任何帮助

【问题讨论】:

  • 您尝试做的事情很奇怪。如果您按 key2 搜索,则子列表中的两个字典都不同。您可以尝试 Master.SelectMany(x=>x).Where(x=>!sub.SelectMany(z=>z).Select(z=>z.Key+"#"+z.Value).Contains( x.Key+"#"+x.Value) && x.Key=="key1");这可以让您参与其中,但您可能需要重新考虑您的设计。

标签: c# linq


【解决方案1】:

需要注意的是,您的数据结构并不理想。由于您将第一个键的第一个值视为“键”,因此您可能需要考虑重新创建结构以使用“SAME1”(和类似值)作为键。

也就是说,您仍然可以在“单行”LINQ 语句中完成这两个查询。

var masterOnly = Master.Where(m => 
    !sub.Select(s => s.First().Value).Contains(m.First().Value)
).ToList();

在仅主场景中,我们使用 Where 子句允许我们首先构建一个子 -> 第一 -> 值的集合,然后我们根据该集合检查循环中的每个主 -> 第一 -> 值。如果该值不存在,则返回该值。

var hasChanged = Master.Where(m => 
    sub.FirstOrDefault(s => 
        s.First().Value == m.First().Value)?.SequenceEqual(m) == false)
    .ToList();

在这种情况下,我们可以利用 C#6 的空传播运算符来避免需要使用 .ForEach() 在循环中构建匹配,因为如果值为空,我们的 SequenceEquals 检查将被忽略。

在我们有匹配的情况下,我们希望明确地将其序列与我们的主集合进行比较,如果任何条目不匹配,我们将其返回。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-03
    • 2020-01-26
    • 2013-05-15
    • 1970-01-01
    • 2018-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多