【问题标题】:Finding duplicate lists in dictionary and print Key of the duplicated list在字典中查找重复列表并打印重复列表的键
【发布时间】:2021-09-01 00:00:32
【问题描述】:

如果有完全匹配的值列表,我有兴趣在字典中查找键

下面是一本字典,其中列出了与班级相关的学生列表。

var studentsInClass = new Dictionary<string, List<string>>();

studentsInClass.Add("Maths", new List<string> { "James", "Bob", "Sophia" });
studentsInClass.Add("English", new List<string> { "James", "Bob", "Sophia", "Mel" });
studentsInClass.Add("History", new List<string> { "Hannah" });
studentsInClass.Add("Geography", new List<string> { "Paul", "Zack" });
studentsInClass.Add("Art", new List<string> { "Paul", "Zack" });
   

例如,我希望将 GeographyArt 类/键视为 PaulZack (只有那两个)在这两个类中。 JamesBobSophia 都使用 数学英语MelEnglish,所以不是完全匹配。

我在这里关注了一个类似的问题Finding duplicate values in dictionary and print Key of the duplicate element

但我认为这不适用于列表或引用类型

【问题讨论】:

  • 欢迎来到 StackOverflow。到目前为止,您尝试过什么?您在哪里卡住了?
  • 排序重要吗?
  • 顺序无所谓

标签: c# linq dictionary collections duplicates


【解决方案1】:

您可以按字符串进行分组,该字符串是通过连接字典中列表的项目而创建的。这样,您就可以避免比较两个具有相同项目但指向不同引用的列表的问题。

var groups = studentsInClass.GroupBy(x => string.Join("", x.Value)).Where(x => x.Count() > 1);

在这里,如果这些组有多个项目(在您的示例中为 Geography 和 Art),您可以对它们进行分组和过滤。

在线演示:https://dotnetfiddle.net/Up72sw

注意:上面的代码会考虑学生的顺序。如果 Geography 是“Zack”、“Paul”,它不会认出它是一样的。如果您想忽略商品的顺序,请在加入商品之前对其进行排序:

var groups = studentsInClass.GroupBy(x => string.Join("", x.Value.OrderBy(y => y))).Where(x => x.Count() > 1);

【讨论】:

    【解决方案2】:

    Linq 可以使这个例子更好一些,但由于我猜这是一个入门课程的练习,所以我用循环来完成它。

                var studentsInClass = new Dictionary<string, List<string>>();
    
                studentsInClass.Add("Maths", new List<string> { "James", "Bob", "Sophia" });
                studentsInClass.Add("English", new List<string> { "James", "Bob", "Sophia", "Mel" });
                studentsInClass.Add("History", new List<string> { "Hannah" });
                studentsInClass.Add("Geography", new List<string> { "Paul", "Zack" });
                studentsInClass.Add("Art", new List<string> { "Paul", "Zack" });
    
                var identicalClasses = new Dictionary<string, List<string>>();
                /*iterate all key-value pairs in the just created dictionary*/
                foreach (KeyValuePair<string, List<string>> entry in studentsInClass)
                {
                    foreach (KeyValuePair<string, List<string>> entry2 in studentsInClass)
                    {
                        /* first we check if we're verifying a key that isn't the entry key itself.
                         * Secondly, we check if the list contains all elements in the second list.
                         * Finally, we make sure the lists are the same size.
                         */ 
                        if (entry.Key != entry2.Key && entry.Value.All(entry2.Value.Contains) && entry.Value.Count == entry2.Value.Count) //If order matters, you can use entry.Value.SequenceEqual(entry2.Value)
                        {
                            /*add the key-value pair to a dict which we can use somewhere else.*/
                            identicalClasses.Add(entry.Key, entry.Value);
                            //Just to show the keys we've added to our identicalClasses list
                            Console.WriteLine("key = " + entry.Key);
                            //We need to break since we don't want to list the key multiple times should there be more than 2 identical classes.
                            break;
                        }
                    }
                }
    

    【讨论】:

      【解决方案3】:

      如果订购确实很重要,那么您可以利用Enumerable.SequenceEqual

      我能想到的最简单的解决方案:

      foreach(var lhs in studentsInClass)
          foreach(var rhs in studentsInClass)
          {
              if(lhs.Key == rhs.Key) continue;
              if(Enumerable.SequenceEqual(lhs.Value, rhs.Value))
                  Console.WriteLine(lhs.Key + " + " + rhs.Key);
          }
      

      这将打印:

      Geography + Art
      Art + Geography
      

      【讨论】:

        猜你喜欢
        • 2011-11-02
        • 2019-01-15
        • 2023-03-13
        • 2022-01-22
        • 2013-07-06
        • 2021-06-03
        • 2021-11-17
        • 1970-01-01
        相关资源
        最近更新 更多