在字典中查找重复列表并打印重复列表的键
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" );
例如,我希望将 Geography 和 Art 类/键视为 Paul 和 Zack (只有那两个)在这两个类中。 James、Bob 和 Sophia 都使用 数学 和 英语,Mel 是 English,所以不是完全匹配。
我在这里关注了一个类似的问题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
【讨论】:
以上是关于在字典中查找重复列表并打印重复列表的键的主要内容,如果未能解决你的问题,请参考以下文章