linq를 사용하여 목록에서 중복 제거
수업이 있습니다.Items
와 함께properties (Id, Name, Code, Price)
.
의 목록Items
중복된 항목으로 채워집니다.
예:
1 Item1 IT00001 $100
2 Item2 IT00002 $200
3 Item3 IT00003 $150
1 Item1 IT00001 $100
3 Item3 IT00003 $150
linq를 사용하여 목록에서 중복 항목을 제거하는 방법은 무엇입니까?
var distinctItems = items.GroupBy(x => x.Id).Select(y => y.First());
var distinctItems = items.Distinct();
일부 속성만 일치시키려면 다음과 같은 사용자 정의 동등 비교기를 만듭니다.
class DistinctItemComparer : IEqualityComparer<Item> {
public bool Equals(Item x, Item y) {
return x.Id == y.Id &&
x.Name == y.Name &&
x.Code == y.Code &&
x.Price == y.Price;
}
public int GetHashCode(Item obj) {
return obj.Id.GetHashCode() ^
obj.Name.GetHashCode() ^
obj.Code.GetHashCode() ^
obj.Price.GetHashCode();
}
}
그런 다음 다음과 같이 사용합니다.
var distinctItems = items.Distinct(new DistinctItemComparer());
Distinct 쿼리를 무시하는 것이 있으면 MoreLinq를 보고 DistinctBy 연산자를 사용하여 ID로 구별되는 개체를 선택할 수 있습니다.
var distinct = items.DistinctBy( i => i.Id );
이것이 제가 린크와 함께 할 수 있었던 방법입니다.도움이 되길 바랍니다.
var query = collection.GroupBy(x => x.title).Select(y => y.FirstOrDefault());
범용 확장 방법:
public static class EnumerableExtensions
{
public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> enumerable, Func<T, TKey> keySelector)
{
return enumerable.GroupBy(keySelector).Select(grp => grp.First());
}
}
사용 예:
var lstDst = lst.DistinctBy(item => item.Key);
목록에서 중복 항목을 제거하기 위한 세 가지 옵션이 있습니다.
- 사용자 정의 동등 비교 사용
Distinct(new DistinctItemComparer())
@크리스찬 헤이터가 언급했듯이. 사용하다
GroupBy
하지만 참고하시기 바랍니다.GroupBy
모든 열을 기준으로 그룹화해야 합니다. 왜냐하면 만약 당신이 그냥 그룹화한다면Id
중복 항목을 항상 제거하지는 않습니다.예를 들어 다음과 같은 예를 생각해 보십시오.List<Item> a = new List<Item> { new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100}, new Item {Id = 2, Name = "Item2", Code = "IT00002", Price = 200}, new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150}, new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100}, new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150}, new Item {Id = 3, Name = "Item3", Code = "IT00004", Price = 250} }; var distinctItems = a.GroupBy(x => x.Id).Select(y => y.First());
이 그룹의 결과는 다음과 같습니다.
{Id = 1, Name = "Item1", Code = "IT00001", Price = 100} {Id = 2, Name = "Item2", Code = "IT00002", Price = 200} {Id = 3, Name = "Item3", Code = "IT00003", Price = 150}
어떤 것이 잘못된 것입니까? 그것은 그것이 고려하기 때문입니다.
{Id = 3, Name = "Item3", Code = "IT00004", Price = 250}
중복하여따라서 올바른 쿼리는 다음과 같습니다.var distinctItems = a.GroupBy(c => new { c.Id , c.Name , c.Code , c.Price}) .Select(c => c.First()).ToList();
3. 재정의
Equal
그리고.GetHashCode
항목 클래스:public class Item { public int Id { get; set; } public string Name { get; set; } public string Code { get; set; } public int Price { get; set; } public override bool Equals(object obj) { if (!(obj is Item)) return false; Item p = (Item)obj; return (p.Id == Id && p.Name == Name && p.Code == Code && p.Price == Price); } public override int GetHashCode() { return String.Format("{0}|{1}|{2}|{3}", Id, Name, Code, Price).GetHashCode(); } }
그런 다음 다음과 같이 사용할 수 있습니다.
var distinctItems = a.Distinct();
사용하다Distinct()
그러나 기본 등식 비교기를 사용하여 값을 비교하므로 그 이상의 값을 원하는 경우 자신의 비교기를 구현해야 합니다.
예를 보려면 http://msdn.microsoft.com/en-us/library/bb348436.aspx 을 참조하십시오.
이 확장 방법을 사용해 보십시오.이것이 도움이 되기를 바랍니다.
public static class DistinctHelper
{
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
var identifiedKeys = new HashSet<TKey>();
return source.Where(element => identifiedKeys.Add(keySelector(element)));
}
}
용도:
var outputList = sourceList.DistinctBy(x => x.TargetProperty);
List<Employee> employees = new List<Employee>()
{
new Employee{Id =1,Name="AAAAA"}
, new Employee{Id =2,Name="BBBBB"}
, new Employee{Id =3,Name="AAAAA"}
, new Employee{Id =4,Name="CCCCC"}
, new Employee{Id =5,Name="AAAAA"}
};
List<Employee> duplicateEmployees = employees.Except(employees.GroupBy(i => i.Name)
.Select(ss => ss.FirstOrDefault()))
.ToList();
또 다른 해결책, 아름답지 않은 구매가 가능합니다.
저는 RAM 모듈 정보를 기록하기 위해 두 가지 속성이 "GRADE"와 "SPD"인 "MEMDES"라는 요소를 가진 XML 파일을 가지고 있습니다.SPD에는 중복 항목이 많습니다.
중복된 항목을 제거하는 데 사용하는 코드는 다음과 같습니다.
IEnumerable<XElement> MList =
from RAMList in PREF.Descendants("MEMDES")
where (string)RAMList.Attribute("GRADE") == "DDR4"
select RAMList;
List<string> sellist = new List<string>();
foreach (var MEMList in MList)
{
sellist.Add((string)MEMList.Attribute("SPD").Value);
}
foreach (string slist in sellist.Distinct())
{
comboBox1.Items.Add(slist);
}
IEquality Comparer를 작성하고 싶지 않을 때 다음과 같은 방법을 사용할 수 있습니다.
class Program
{
private static void Main(string[] args)
{
var items = new List<Item>();
items.Add(new Item {Id = 1, Name = "Item1"});
items.Add(new Item {Id = 2, Name = "Item2"});
items.Add(new Item {Id = 3, Name = "Item3"});
//Duplicate item
items.Add(new Item {Id = 4, Name = "Item4"});
//Duplicate item
items.Add(new Item {Id = 2, Name = "Item2"});
items.Add(new Item {Id = 3, Name = "Item3"});
var res = items.Select(i => new {i.Id, i.Name})
.Distinct().Select(x => new Item {Id = x.Id, Name = x.Name}).ToList();
// now res contains distinct records
}
}
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
}
언급URL : https://stackoverflow.com/questions/1606679/remove-duplicates-in-the-list-using-linq
'programing' 카테고리의 다른 글
런타임 오류:비동기 + apscheduler의 스레드에 현재 이벤트 루프가 없습니다. (0) | 2023.05.13 |
---|---|
GitHub API에서 기본 인증을 위해 사용자 이름 및 암호와 함께 Invoke-WebRequest 사용 (0) | 2023.05.13 |
모듈을 설치하는 동안 "레지스트리에서 가져오지 못했습니다." (0) | 2023.05.13 |
보안 웹 서비스에도 액세스하는 iOS 앱에서 Facebook 인증을 위한 설계 (0) | 2023.05.13 |
특정 길이의 하위 목록을 인쇄하려면 어떻게 해야 합니까? (0) | 2023.05.13 |