在字典中查找重复列表并打印重复列表的键

Posted

技术标签:

【中文标题】在字典中查找重复列表并打印重复列表的键【英文标题】: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

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

【问题讨论】:

欢迎来到 ***。到目前为止,您尝试过什么?您在哪里卡住了? 排序重要吗? 顺序无所谓 【参考方案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

【讨论】:

以上是关于在字典中查找重复列表并打印重复列表的键的主要内容,如果未能解决你的问题,请参考以下文章

查找字典的最大值并打印键、值对[重复]

如何在python中反转字典并从重复的键值中创建一个列表

如何查看字典/列表并获取位置和布尔值 [重复]

在字典列表中查找重复值

python中怎么重复打印

将字典的键与 List 的值进行比较,并返回所有匹配的值,包括重复值