2017-04-12 77 views
2

我的字典比較2的List <詞典<字符串,對象>>在C#

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

我的兩個字典具有相同的鍵名的名單2。

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: 正如你可以看到,我可以使用的鍵(鍵1,因爲它是所有相同的值)從詞典中的第一列表中,以查看是否在該第二字典和如果它存在該值我不想在新的List>中丟失字典。

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

方案2: 如果想在字典中的子列表字典的一個包含相同值的鍵1,我要檢查字典一樣的其他值,如果這些密鑰的任何值有改變,如果他們有我想要一個新的 名單有原來的。

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

你想要做的事情很奇怪。如果你通過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」);讓你成爲你的一部分,但你可能想重新考慮你的設計。 – Hakunamatata

回答

0

作爲一個警告,您的數據結構並不理想。由於您將第一個鍵的第一個值視爲「鍵」,因此您可能需要考慮重新創建結構以使用「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的檢查被忽略。

在我們有匹配的情況下,我們希望將其序列與我們的主集合進行顯式比較,如果有任何條目不匹配,我們會將其返回。

相關問題