比较两个字典(字典<字符串,列表>)
我需要检查Dictionary<string, List<string>>
类型的两个字典是否相同。到目前为止,我有这样的:比较两个字典(字典<字符串,列表<string>>)
// dictionaries are already defined, so no parameters are required
private bool DictionariesEqual()
{
return dictionary1.SequenceEqual(dictionary2);
}
我以为这只是检查键和值的顺序是一样的,这不是我想要的,因为的顺序并不重要,每个只有名称键和值。
有没有办法检查不同字符串的字典,如果发现第一个不匹配,就返回false?
编辑
感谢您的帮助,但价值变动仍然无法识别。
更具体地讲,这里的功能(感谢@juharr),我如何使用它:
private bool DictionaryContentChanged()
{
if(synonymDictionary.Count != temporaryDictionary.Count ||
synonymDictionary.Keys.Except(temporaryDictionary.Keys).Any() ||
!synonymDictionary.Join(
temporaryDictionary,
kvp => kvp.Key,
kvp => kvp.Key,
(kvp1, kvp2) => new
{
l1 = kvp1.Value,
l2 = kvp2.Value
})
.All(a => a.l1.Count == a.l2.Count && !a.l1.Except(a.l2).Any()))
return true;
return false;
{
我把它改成按一定的间隔反复检查更改的更新功能:
void Update(int interval)
{
while(!this.IsDisposed)
{
Set.Timer(interval);
if(DictionaryContentChanged())
{
MessageBox.Show("Changes detected");
}
else
{
// move on
}
}
}
当我添加,删除或更改值没有任何反应。消息框仅在密钥更改或key.Count更改时才显示。这可能与比较词典的功能有关吗?
请记住每个KeyValuePair的值代表一个通用列表。
排序两个字典,并比较其
bool result2 = dictionary1.OrderBy(r=>r.Key).SequenceEqual(dictionary2.OrderBy(r=>r.Key));
这不起作用,因为它将引用列表与其内容进行比较。 – juharr 2014-10-08 13:22:14
没有测试,但我想下面可能工作:
if (dictionary1.Count != dictionary2.Count) return false;
foreach (var kv in dictionary1) {
if (!dictionary2.ContainsKey(kv.Key) return false;
List list = dictionary2[kv.Key];
if (!list.Count != dictionary1[kv.Key].Count) return false;
foreach(var value in kv.Value) {
if(!list.Contains(value)) return false;
}
}
return true;
编辑:我加了一些长度检查。
这里有一个LINQ版本
dic1.Count == dic2.Count &&
!dic1.Keys.Except(dic2.Keys).Any() &&
dic1.Join(
dic2,
kvp => kvp.Key,
kvp => kvp.Key,
(kvp1, kvp2) => new
{
l1 = kvp1.Value,
l2 = kvp2.Value
})
.All(a => a.l1.Count == a.l2.Count && !a.l1.Except(a.l2).Any())
首先,它可以确保字典有相同数量的项目,那么它可以确保它们具有相同的密钥。然后它将它们连接到它们的键上,并确保具有相同键的所有列表具有相同的计数和相同的内容。
编辑
这里有一些方法来得到相对的回报值。
用()把整个东西包起来放一个!前面。
!(dic1.Count == dic2.Count &&
!dic1.Keys.Except(dic2.Keys).Any() &&
dic1.Join(
dic2,
kvp => kvp.Key,
kvp => kvp.Key,
(kvp1, kvp2) => new
{
l1 = kvp1.Value,
l2 = kvp2.Value
})
.All(a => a.l1.Count == a.l2.Count && !a.l1.Except(a.l2).Any()))
如果你发布的不是,那么你得到这个,请注意,您必须将ANDS(&&
)改为口服补液盐(||
)。
dic1.Count != dic2.Count ||
dic1.Keys.Except(dic2.Keys).Any() ||
!dic1.Join(
dic2,
kvp => kvp.Key,
kvp => kvp.Key,
(kvp1, kvp2) => new
{
l1 = kvp1.Value,
l2 = kvp2.Value
})
.All(a => a.l1.Count == a.l2.Count && !a.l1.Except(a.l2).Any())
这是基于De Morgan's Law指出
Not(A And B) = Not A Or Not B
另一种选择是改变你的方法从DictionaryContentChanged
到DictionaryContentSame
,只是否定它,你使用它,如果需要的。
请问你为什么不排除我的答案? – HimBromBeere 2014-10-08 14:55:00
对不起。这是因为我很快接受了它,当我意识到字典的关键变化已经被注册了,但是当我意识到价值变化没有被你的比较看到时,我就不接受你的答案。 – betaFlux 2014-10-08 15:16:03
您的值是否在列表中实际上是字符串或任意对象?在第一种情况下,我的解决方案应该工作,否则您应该在每种可能类型的对象上实现Equals(和GetHashCode)。 – HimBromBeere 2014-10-09 06:05:57