比较2 List <dictionary <string,object>&gt;在c#中

时间:2017-04-12 01:33:05

标签: c# linq

我有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,因为它是相同的值)来查看第二个字典中是否存在该值,如果不存在,我想要一个缺少的字典新名单&gt;

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本身获得所需的输出?

感谢任何帮助

1 个答案:

答案 0 :(得分:0)

作为一个警告,您的数据结构并不理想。由于您将第一个键的第一个值视为&#34;键&#34;,您可能需要考虑重新创建结构以使用&#34; SAME1&#34; (和类似的值)作为键。

那就是说,你仍然可以在&#34;单行&#34; LINQ语句。

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

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

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

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

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