【问题标题】:c# ToDictionary with ContainsKey checkc# ToDictionary with ContainsKey 检查
【发布时间】:2012-04-13 11:05:04
【问题描述】:

我有一个要放入字典的列表,为简单起见,插入的值都是相同的。

我可以使用 foreach 循环。

    List<string> list = new List<string>();
    list.Add("Earth");
    list.Add("Wind");
    list.Add("Fire");
    list.Add("Water");
    list.Add("Water"); // Will NOT BE INSERTED using the foreach loop

    var myDictionary= new Dictionary<string, int>();
    foreach (string value in list)
    {
        if (!myDictionary.ContainsKey(value))
        {
        myDictionary.Add(value, 1);
        }
    }

以上工作。

但我想用 ToDictionary 做同样的事情 -

    Dictionary<string, int> myDictionary2 = list.ToDictionary(i => i, i => 1);

这当然失败了,因为我添加了两次“水”。

使用 ToDictionary 时检查重复条目的正确方法是什么?

【问题讨论】:

    标签: c# linq dictionary lambda duplicates


    【解决方案1】:

    Distinct 是一种避免重复密钥问题的选项。如果您需要重复计数,您可以尝试类似GroupBy 的方法,如下所示:

    var dict = list.GroupBy(i => i).ToDictionary(g => g.Key, g => g.Count());
    

    如果您的应用程序不仅仅是一个简单的字符串列表/重复计数结构,您可能会从选择不同的结构(如 Lookup)中获得一些好处,您可以通过调用 ToLookup 扩展来获得 - 或者可能会使用像我上面使用的 GroupBy 这样的分组。

    【讨论】:

      【解决方案2】:

      您可以使用Distinct() 过滤掉重复项:

      Dictionary<string, int> myDictionary2 = list.Distinct().ToDictionary(i => i, i => 1);
      

      同样的方法也会使您的传统循环更加清晰,因为您不必“手动”检查重复项:

      foreach (string value in list.Distinct())
      {
          myDictionary.Add(value, 1);
      }
      

      【讨论】:

      • @Gabe:不确定我不理解您在问题上下文中的评论-您能澄清一下吗?
      • 所有值为 1 的字典本质上只是一个集合。如果用户从不访问这些值,则不需要实际的字典。
      • @Gabe:除非他当然要使用它来存储计数(不是 OP 出现的那样)。添加HashSet 答案。
      • 是的 - 我接受了评论 “为简单起见,插入的值都是相同的” 表示 OP 实际上需要值 - 否则只是 HashSet&lt;string&gt;完全不需要检查不同的值就可以完成这项工作。
      • 真正的需求是找到一个好的“使用 ToDictionary 时检查重复条目的方法?”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-01
      • 1970-01-01
      • 2011-08-26
      • 1970-01-01
      • 1970-01-01
      • 2019-11-26
      相关资源
      最近更新 更多