使用linq从字段列表中删除重复

时间:2017-01-06 13:53:08

标签: c# linq

我是C#和Linq的新手我面临一个问题,即删除重复记录我需要删除那些没有Dept的重复记录。以下是使用员工列表的快速示例

 private static void Main()
    {
        List<Employee> empList = new List<Employee>();

        empList.Add(new Employee() { ID = 1, Name = "John", Age=23, Dept='computer'});
        empList.Add(new Employee() { ID = 2, Name = "Mary", Age=25, Dept='computer'});
        empList.Add(new Employee() { ID = 3, Name = "Amber",Age=23, Dept=''});
        empList.Add(new Employee() { ID = 4, Name = "Kathy",Age=25, Dept=''});
        empList.Add(new Employee() { ID = 5, Name = "Lena", Age=27, Dept='computer'});
        empList.Add(new Employee() { ID = 6, Name = "John", Age=28, Dept=''});
        empList.Add(new Employee() { ID = 7, Name = "Kathy",Age=27, Dept='Tester'});
 empList.Add(new Employee() { ID = 8, Name = "John", Age=23, Dept='computer'});
        var dup = empList
            .GroupBy(x => new { x.FName })
            .Select(group => new { Name = group.Key, Count = group.Count() })
            .OrderByDescending(x => x.Count);

        foreach (var x in dup)
        {
            Response.Write(x.Count + " " + x.Name);
        }
    }
    class Employee
    {
        public int ID { get; set; }
        public string FName { get; set; }
        public int Age { get; set; }
        public char Dept { get; set; }
    }

最终输出看起来像这样 输出示例: -

    empList.Add(new Employee() { ID = 1, Name = "John", Age=23, Dept='computer'});
        empList.Add(new Employee() { ID = 2, Name = "Mary", Age=25, Dept='computer'});
        empList.Add(new Employee() { ID = 3, Name = "Amber",Age=23, Dept=''}); 
        empList.Add(new Employee() { ID = 5, Name = "Lena", Age=27, Dept='computer'});
        empList.Add(new Employee() { ID = 7, Name = "Kathy",Age=27, Dept='Tester'});
 empList.Add(new Employee() { ID = 8, Name = "John", Age=23, Dept='computer'});

我需要删除那些没有部门的重复记录。

条件1 重复记录将多次出现,但是一个单独的记录不具有应该删除的部门。剩余记录将显示在输出

5 个答案:

答案 0 :(得分:1)

由于ID是唯一的,您可以使用此方法(Dept似乎是一个字符串):

var empDupNoDepartment = empList
    .GroupBy(x => String.IsNullOrEmpty(x.Dept) ? int.MinValue : x.ID)
    .Select(group => group.First())
    .ToList();

这只保留第一位空Dept的员工。

答案 1 :(得分:0)

from e in empList
group e by e.Name into g
select g.FirstOrDefault(e => !String.IsNullOrEmpty(e.Dept)) ?? g.First();

只需按名称分组,然后选择第一名有Dept的员工或只选择第一名员工。

输出:

[
  { "ID": 1, "Name": "John", "Age": 23, "Dept": "computer" },
  { "ID": 2, "Name": "Mary", "Age": 25, "Dept": "computer" },
  { "ID": 3, "Name": "Amber", "Age": 23,"Dept": "" },
  { "ID": 7, "Name": "Kathy", "Age": 27, "Dept": "Tester" },
  { "ID": 5, "Name": "Lena", "Age": 27, "Dept": "computer" }
]

如果你想保留所有非空Dept的条目,那么

Func<Employee, bool> hasDept = e => !String.IsNullOrEmpty(e.Dept);
var result = empList
       .GroupBy(e => e.Name)
       .SelectMany(g => g.Any(hasDept) ? g.Where(hasDept) : g.Take(1));

查询语法:

from e in empList
group e by e.Name into g
from e in g.Any(hasDept) ? g.Where(hasDept) : g.Take(1)
select e;

输出:

[
  { "ID": 1, "Name": "John", "Age": 23, "Dept": "computer" },
  { "ID": 8, "Name": "John", "Age": 23, "Dept": "computer" },  <== difference
  { "ID": 2, "Name": "Mary", "Age": 25, "Dept": "computer" },
  { "ID": 3, "Name": "Amber", "Age": 23,"Dept": "" },
  { "ID": 7, "Name": "Kathy", "Age": 27, "Dept": "Tester" },
  { "ID": 5, "Name": "Lena", "Age": 27, "Dept": "computer" }
]

答案 2 :(得分:0)

创建此类:

class Dept
{
    public int Count { get; set; }
    public string Name { get; set; }
    public List<Employee> Employees { get; set; }
}

以下是查询:

var dup = empList
    .GroupBy(x => new { x.Name })

    // Employees with duplicate name
    .Select(group => new { Emps = group.Select(x => x)})

    // From duplicates select only those that have a department 
    .SelectMany(x => {
        var emps = x.Emps.Where(y => !string.IsNullOrWhiteSpace(y.Dept));
        var employeesWithDept = emps.GroupBy(g => g.Name );


        IEnumerable<Dept> a = 
        employeesWithDept.Select(g => new Dept { Employees = g.ToList(), Name = g.Key.ToString(), Count = g.Count()});
        return a;
    })
    .OrderByDescending(x => x.Count);

答案 3 :(得分:-1)

你在这里有一个例子,说明为什么某个人的名字对于任何事情来说都是一个可怕的主键。

所有价值观:

var hasDept = empList.Where(x=>x.Dept != null && x.Dept.Trim() != string.Empty).ToList();

不同的价值观:

var hasDept =  empList.Where(x=>x.Dept != null && x.Dept.Trim() != string.Empty).Distinct().ToList();

那些会让你成为有部门的人。如果你也想要那些没有一个,但没有重复的条目有一个部门,最简单的方法可能是:

var noDept = empList.Where(x=>x.Dept == null || x.Dept.Trim() == string.Empty).Distinct().ToList()  //gets all the ones with no dept

var all = noDept;
foreach(var e in all)
{
        if(hasDept.Where(x.Name == e.Name).Count == 0)
           all.Add(e);
}

答案 4 :(得分:-2)

我不确定,但如果您只是想用Linq删除空的Dept员工,您应该可以这样做:

empList = empList.Where(Dept => !string.IsNullOrWhiteSpace(Dept)).Distinct().ToList()

祝你好运!