比较两个词典(Dictionary<;string、List<;string>;)

本文关键字:string lt gt List 两个 比较 Dictionary | 更新日期: 2023-09-27 18:25:52

我需要检查两个类型为Dictionary<string, List<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
        }
    }
}

当我添加、删除或更改一个值时,不会发生任何事情。只有当钥匙或钥匙发生更改时,才会显示消息框。计数已更改。这可能与比较字典的功能有关吗?

请记住,每个KeyValuePair的值表示一个泛型列表。

比较两个词典(Dictionary<;string、List<;string>;)

未测试,但我想以下可能有效:

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()))

如果你分发not,那么你会得到这个,注意你必须将ands(&&)更改为ors(||)。

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())

这是基于德摩根定律,该定律指出

Not(A And B) = Not A Or Not B

另一种选择是将方法从DictionaryContentChanged更改为DictionaryContentSame,如果需要,只需在使用它的地方取反即可。

对两个字典进行排序并比较

bool result2 = dictionary1.OrderBy(r=>r.Key).SequenceEqual(dictionary2.OrderBy(r=>r.Key));