2013-07-31 1 views
1

В моем проекте у меня возникла критическая проблема: у меня есть коллекция всех Employee s в коллекции. Некоторые из Employee с имеют тот же LName:Как получить все дубликаты записей с помощью linq

public class Employee 
{ 
    public int ID { get; set; } 
    public string FName { get; set; } 
    public string MName { get; set; } 
    public string LName { get; set; } 
    public DateTime DOB { get; set; } 
    public char Gender { get; set; } 
} 

public class MyClass 
{ 
    public List<Employee> GetAll() 
    { 
     List<Employee> empList = new List<Employee>(); 
     empList.Add(new Employee() 
     { 
      ID = 1, 
      FName = "John", 
      MName = "", 
      LName = "Shields", 
      DOB = DateTime.Parse("12/11/1971"), 
      Gender = 'M' 
     }); 
     empList.Add(new Employee() 
     { 
      ID = 2, 
      FName = "Mary", 
      MName = "Matthew", 
      LName = "Jacobs", 
      DOB = DateTime.Parse("01/17/1961"), 
      Gender = 'F' 
     }); 
     empList.Add(new Employee() 
     { 
      ID = 3, 
      FName = "Amber", 
      MName = "Carl", 
      LName = "Agar", 
      DOB = DateTime.Parse("12/23/1971"), 
      Gender = 'M' 
     }); 
     empList.Add(new Employee() 
     { 
      ID = 4, 
      FName = "Kathy", 
      MName = "", 
      LName = "Foxsss", 
      DOB = DateTime.Parse("11/15/1976"), 
      Gender = 'F' 
     }); 
     empList.Add(new Employee() 
     { 
      ID = 5, 
      FName = "Lena", 
      MName = "Ashco", 
      LName = "Bilton", 
      DOB = DateTime.Parse("05/11/1978"), 
      Gender = 'F' 
     }); 
     empList.Add(new Employee() 
     { 
      ID = 6, 
      FName = "Susanne", 
      MName = "", 
      LName = "Buck", 
      DOB = DateTime.Parse("03/7/1965"), 
      Gender = 'F' 
     }); 
     empList.Add(new Employee() 
     { 
      ID = 7, 
      FName = "Jim", 
      MName = "", 
      LName = "Hooks", 
      DOB = DateTime.Parse("09/11/1972"), 
      Gender = 'M' 
     }); 
     empList.Add(new Employee() 
     { 
      ID = 8, 
      FName = "Jane", 
      MName = "G", 
      LName = "Hooks", 
      DOB = DateTime.Parse("12/11/1972"), 
      Gender = 'F' 
     }); 
     empList.Add(new Employee() 
     { 
      ID = 9, 
      FName = "Robert", 
      MName = "", 
      LName = "Fox", 
      DOB = DateTime.Parse("06/28/1964"), 
      Gender = 'M' 
     }); 
     empList.Add(new Employee() 
     { 
      ID = 10, 
      FName = "Cindy", 
      MName = "Preston", 
      LName = "Fox", 
      DOB = DateTime.Parse("01/11/1978"), 
      Gender = 'M' 
     }); 

     return empList; 
    } 
} 

Как я могу получить дубликаты записей (на основе LName) из моей коллекции с помощью LINQ?

+1

Вы должны прочитать о [Инициализаторы коллекции] (http://msdn.microsoft.com/en-us/library/vstudio/bb384062.aspx). Кроме того, при использовании инициализаторов объектов круглые скобки являются избыточными :) – khellang

ответ

6

Это не ясно, но похоже, что вы ищете следующее:

var duplicates = GetAll().GroupBy(x => x.LName) 
         .Where(g => g.Count() > 1) 
         .SelectMany(g => g) 
         .ToList() 

Он группирует элемент по LName, принимает только те группы, которые имеют более чем 1 элемент и возвращает их в виде списка.

duplicates будет List<Employee>.

Вы можете сделать это немного лучше, используя ToDictionary вместо ToList:

var duplicates = GetAll().GroupBy(x => x.LName) 
         .Where(g => g.Count() > 1) 
         .ToDictionary(g = > g.Key, g.ToList()); 

Это будет Dictionary<string, List<Employee>> с LName в качестве словаря ключ и список элементов с заданными LName в Value.

+0

Почему бы не '.ToLookup (g => g.Key)'? Кажется намного чище, чем '.ToDictionary (g => g.Key, g.ToList())' –

+0

@pswg Да, это может быть поиск :) – MarcinJuraszek

+0

@pswg извините за это, но когда я использую .ToLookup (g = > g.Key), то это даст мне отличную повторяющуюся запись, но я не буду отмечать все повторяющиеся записи. – Rajpurohit

1

Вам не нужно делать полный подсчет для заданного ключа; вы действительно можете быть немного более эффективными и все еще четко выражать то, что означает, что это будет дубликат. Чтобы проверить наличие дубликатов, вам просто нужно проверить, что после того, как вы пропустить первый пункт, посмотреть, если есть любой остающейся:

var duplicates = GetAll().GroupBy(x => x.LName) 
         .Where(g => g.Skip(1).Any()) 
         .SelectMany(g => g); 

Вы можете преобразовать это в список, если вам нужно с ToList. Или вы можете сказать:

var duplicates = GetAll().GroupBy(x => x.LName) 
         .Where(g => g.Skip(1).Any()) 
         .ToLookup(g => g.Key); 

, чтобы они собирали Employee.LName.

Смежные вопросы