[英]remove duplication from list on field using 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 重復記錄將多次出現,但一條記錄沒有應該刪除的部門。 剩余的記錄將顯示在輸出上
由於 ID 是唯一的,您可以使用這種方法( Dept
似乎是一個字符串):
var empDupNoDepartment = empList
.GroupBy(x => String.IsNullOrEmpty(x.Dept) ? int.MinValue : x.ID)
.Select(group => group.First())
.ToList();
這僅保留第一個Dept
為空的員工。
from e in empList
group e by e.Name into g
select g.FirstOrDefault(e => !String.IsNullOrEmpty(e.Dept)) ?? g.First();
只需按姓名分組,然后選擇第一個有部門的員工或第一個員工。
輸出:
[
{ "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" }
]
創建這個類:
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);
你這里有一個例子,說明為什么某人的名字對於任何事情來說都是一個糟糕的主鍵。
所有值:
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);
}
我不確定,但是如果您只想使用 Linq 刪除空的 Dept 員工,您應該可以這樣做:
empList = empList.Where(Dept => !string.IsNullOrWhiteSpace(Dept)).Distinct().ToList()
此致 !
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.