检查对象列表C#中的重复项

Sof*_*ant 25 linq

我正在寻找一种非常快速的方法来检查对象列表中的重复项.

我想只是循环遍历列表并以这种方式进行手动比较,但我认为linq可能会提供更优雅的解决方案......

假设我有一个对象......

public class dupeCheckee
{
     public string checkThis { get; set; }
     public string checkThat { get; set; }

     dupeCheckee(string val, string val2)
     {
         checkThis = val;
         checkThat = val2;
     }
}
Run Code Online (Sandbox Code Playgroud)

我有一个这些对象的列表

List<dupeCheckee> dupList = new List<dupeCheckee>();
dupList.Add(new dupeCheckee("test1", "value1"));
dupList.Add(new dupeCheckee("test2", "value1"));
dupList.Add(new dupeCheckee("test3", "value1"));
dupList.Add(new dupeCheckee("test1", "value1"));//dupe
dupList.Add(new dupeCheckee("test2", "value1"));//dupe... 
dupList.Add(new dupeCheckee("test4", "value1"));
dupList.Add(new dupeCheckee("test5", "value1"));
dupList.Add(new dupeCheckee("test1", "value2"));//not dupe
Run Code Online (Sandbox Code Playgroud)

我需要找到该列表中的欺骗行为.当我找到它时,我需要做一些额外的逻辑,不一定要删除它们.

当我使用linq时,我的GroupBy如何抛出异常......

'System.Collections.Generic.List<dupeCheckee>' does not contain a definition for 'GroupBy' and no extension method 'GroupBy' accepting a first argument of type 'System.Collections.Generic.List<dupeCheckee>' could be found (are you missing a using directive or an assembly reference?)
Run Code Online (Sandbox Code Playgroud)

这告诉我,我错过了一个图书馆.我很难搞清楚哪一个.

一旦我弄明白了,我怎么会基本上检查这两个条件...... IE checkThis和checkThat都发生了不止一次?

更新:我想出了什么

这是我在快速研究后想出的linq查询...

test.Count != test.Select(c => new { c.checkThat, c.checkThis }).Distinct().Count()
Run Code Online (Sandbox Code Playgroud)

我不确定这是否肯定比这个答案更好......

var duplicates = test.GroupBy(x => new {x.checkThis, x.checkThat})
                   .Where(x => x.Skip(1).Any());
Run Code Online (Sandbox Code Playgroud)

我知道我可以将第一个语句放入if else子句中.我也进行了快速测试.当我期待0时,重复列表给了我1但是它确实正确地称我在我使用的其中一个集合中有重复的事实...

另一种方法完全按照我的预期进行.以下是我用来测试它的数据集....

易受骗的人:

List<DupeCheckee> test = new List<DupeCheckee>{ 
     new DupeCheckee("test0", "test1"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test1", "test2"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test2", "test3"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test3", "test3"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test0", "test5"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test1", "test6"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test2", "test7"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test3", "test8"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test0", "test5"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test1", "test1"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test2", "test2"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test3", "test3"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test4", "test4"),//{ checkThis = "test", checkThat = "test1"}

};
Run Code Online (Sandbox Code Playgroud)

没有欺骗......

     List<DupeCheckee> test2 = new List<DupeCheckee>{ 
     new DupeCheckee("test0", "test1"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test1", "test2"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test2", "test3"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test3", "test3"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test4", "test5"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test5", "test6"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test6", "test7"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test7", "test8"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test8", "test5"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test9", "test1"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test2", "test2"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test3", "test3"),//{ checkThis = "test", checkThat = "test1"}
     new DupeCheckee("test4", "test4"),//{ checkThis = "test", checkThat = "test1"}

};
Run Code Online (Sandbox Code Playgroud)

Bob*_*ale 39

你需要引用System.Linq(例如using System.Linq)

那么你可以做到

var dupes = dupList.GroupBy(x => new {x.checkThis, x.checkThat})
                   .Where(x => x.Skip(1).Any());
Run Code Online (Sandbox Code Playgroud)

这将为您的组提供所有重复项

然后是重复测试

var hasDupes = dupList.GroupBy(x => new {x.checkThis, x.checkThat})
                   .Where(x => x.Skip(1).Any()).Any();
Run Code Online (Sandbox Code Playgroud)

甚至打电话ToList()ToArray()强制计算结果,然后你可以检查欺骗并检查它们.

例如..

var dupes = dupList.GroupBy(x => new {x.checkThis, x.checkThat})
                   .Where(x => x.Skip(1).Any()).ToArray();
if (dupes.Any()) {
  foreach (var dupeList in dupes) {
    Console.WriteLine(string.Format("checkThis={0},checkThat={1} has {2} duplicates",
                      duplist.Key.checkThis, 
                      duplist.Key.checkThat,
                      duplist.Count() - 1));
  }

}
Run Code Online (Sandbox Code Playgroud)

另外

var dupes = dupList.Select((x, i) => new { index = i, value = x})
                   .GroupBy(x => new {x.value.checkThis, x.value.checkThat})
                   .Where(x => x.Skip(1).Any());
Run Code Online (Sandbox Code Playgroud)

它为您提供了每个组中每个项目将原始索引存储在属性中的组index以及属性中的项目value


Mar*_*ris 8

有大量的工作解决方案,但我认为下一个解决方案将更加透明和易于理解,然后以上所有:

var hasDuplicatedEntries = ListWithPossibleDuplicates
                                   .GroupBy(YourGroupingExpression)
                                   .Any(e => e.Count() > 1);
if(hasDuplicatedEntries)
{
   // Do what ever you want in case when list contains duplicates 
}
Run Code Online (Sandbox Code Playgroud)