【问题标题】:Comparing two dictionaries and returning the differences in another dictionary比较两个字典并返回另一个字典中的差异
【发布时间】:2013-08-23 19:43:28
【问题描述】:

我有两个字典,我希望比较两个字典的键/对值。当我比较它们时,如果第二个字典中的值不同,我想保持它们的配对并将其存储到字典 3 中。

所以,如果我有字典 1 和 (<1,T><2,T><3,T>),字典 2 和 (<1,T><2,F><3,T>),我希望字典 3 看起来像 (<2,F>)。

我不知道从哪里开始。我有正确获取所有数据的字典,但现在我不确定如何设置比较。

private Dictionary<int, bool> CompareDictionaries(Dictionary<int, bool> dic2)
{
    Dictionary<int,bool> dictionary3 = new Dictionary<int,bool>();

    foreach (KeyValuePair<int, bool> pair in dictionary1)
    {
        // keep KeyValuePair of dic2
        // dictionary3.add(KeyValuePair of dic 2)
    }

    return dictionary3;
}

对此的任何帮助将不胜感激。我很肯定我可以用字典完成我的目标。在获得第三本字典后,我将更新表格中的一些信息,然后刷新我正在显示的列表,但这部分要容易得多,然后找出这部分需要哪些方法和算法。任何帮助总是非常非常感谢。谢谢各位。

【问题讨论】:

    标签: c# data-structures dictionary .net-4.0


    【解决方案1】:
    var dict3 = dict2.Except(dict1).ToDictionary(x => x.Key, x => x.Value);
    

    【讨论】:

    • 这里需要ToDictionary吗?
    • @KingKing 既然 OP 说他想要字典中的结果,而不是 IEnumerable&lt;KeyValuePair&gt;,是的。
    • @Servy 这个private Dictionary&lt;int, bool&gt; CompareDictionaries(Dictionary&lt;int, bool&gt; dic2) 怎么样? dict2Dictionarydictionary1KeyValuePair
    • @KingKing Dictionary&lt;K,V&gt; 实现 IEnumerable&lt;KeyValuePair&lt;K,V&gt;&gt;。所有的字典都是序列,不是所有的序列都是字典。把字典当作一个序列很好,把一个序列当作字典就不行了。
    • @NitroFrost 我认为你需要阅读一些关于 Linq + Lambda 的文档
    【解决方案2】:
    return dictionary1.Where(kvp => dic2[kvp.Key] != kvp.Value)
        .ToDictionary(kvp => kvp.Key, kvp => dic2[kvp.Key]);
    

    如果字典 1 包含字典 2 中不存在的任何键,则会抛出此错误。不确定这是否是问题的预期业务功能。

    【讨论】:

      【解决方案3】:

      我做了类似的事情,但返回了一个匿名类型而不是字典,因为我想清楚地看到增量

      var aBeforeDictionary = new Dictionary<string, string>(){ {"asdf", "asdf"}, {"few","less"}, {"curve", "ball"}};
      var anAfterDictionary = new Dictionary<string, string>(){ {"asdf", "asdf"}, {"fun", "guy"}, {"few","more"}};
      
      var myBefores = aBeforeDictionary.Except(anAfterDictionary);
      var myAfters = anAfterDictionary.Except(aBeforeDictionary);
      
      var affectedKeys = myBefores.Select(aPair => aPair.Key).Union(myAfters.Select(aPair => aPair.Key));
      
      string aValue;
      var output = affectedKeys.Select(aKey => new {
                                       Key = aKey,
                                       Before = aBeforeDictionary.TryGetValue(aKey, out aValue) ? aValue : "",
                                       After = anAfterDictionary.TryGetValue(aKey, out aValue) ? aValue : ""
                                   });
      
      output.Dump();
      

      Dump() 语法是 LinqPad 扩展方法。结果如下:

      【讨论】:

        【解决方案4】:

        这是我的尝试;-)

            private Dictionary<int, bool> CompareDictionaries(Dictionary<int, bool> dic1, Dictionary<int, bool> dic2)
            {
                Dictionary<int, bool> dic3 ;
        
                dic3  = new Dictionary<int, bool>();
        
                foreach (KeyValuePair<int, bool> pair in dic1)
                {
                    // keep KeyValuePair of dic2
                    if ( ! ((dic2.ContainsKey(pair.Key)) && (dic2[pair.Key] == pair.Value)))
                    {
                        dic3.Add(pair.Key, pair.Value);
                    }
                }
                return dic3;
            }
        

        【讨论】:

        • 您可以使用TryGetValue在一次调用中执行 ContainsKey 检查和值查找。
        • @Servy 谢谢...无论如何,LINQ 解决方案非常干净,任何其他答案都会看起来很糟糕;-)
        • 不,这对OP可能有用也可能没用,但是.net2.0下的人肯定需要这样的解决方案
        • 我使用的是 4.0.我想我应该这样标记它,不是吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-26
        • 2021-05-22
        相关资源
        最近更新 更多