
LINQ에서 중복 제거할 일이 생각보다 많다. 속성 기준으로 중복 제거하거나, 조건 유지하며 중복 제거해야하거나..
이번 글에서는 DistinctBy()부터 GroupBy + First() 조합, 그리고 EqualityComparer 사용법을 알아보려고한다
📚 목차
1. Distinct() 기본
2. DistinctBy() 사용법 (속성 기준 중복 제거)
3. GroupBy + 조건 유지하며 중복 제거
4. ToDictionary 중복 키 오류 해결법
5. EqualityComparer로 중복 제거
6. Select().Distinct() 활용
7. 마무리
1. Distinct() 기본
Distinct()
는 전체 객체를 기준으로 중복을 제거한다.
var result = items.Distinct();
동일 객체 기준이라, 특정 속성으로 중복 제거하고 싶다면 IEqualityComparer
를 구현하거나 DistinctBy()
를 사용해야 한다.
2. DistinctBy() 사용법 (속성 기준 중복 제거)
.NET 6 이상에서는 DistinctBy()
를 이용해 특정 속성 기준으로 중복을 쉽게 제거할 수 있다.
var result = users.DistinctBy(u => u.Email);
→ 같은 Email을 가진 사용자는 하나만 남는다.
✔ 언제 쓰이나?
회원 리스트에서 Email이 중복되는 경우, 중복된 사용자 중 하나만 남기고 싶을 때 주로 사용한다.
3. GroupBy + 조건 유지하며 중복 제거
예제: 같은 Email을 가진 사용자 중, 가장 먼저 가입한 사용자만 남기기
var result = users
.GroupBy(u => u.Email)
.Select(g => g.OrderBy(u => u.DateJoined).First());
✔ 예제 설명
- GroupBy(u => u.Email)
로 Email 기준 그룹화
- 각 그룹을 가입일(DateJoined
) 오름차순 정렬한 후, 첫 번째 항목을 선택한다.
📌 예상 출력 결과
Email: test@example.com, JoinedAt: 2023-01-01
Email: user@example.com, JoinedAt: 2024-03-01
→ 같은 Email의 사용자 중 가장 먼저 가입한 사용자만 남는다.
4. ToDictionary 중복 키 오류 해결법
❌ 오류 상황
var dict = users.ToDictionary(u => u.Email);
⚠️ 오류 메시지
System.ArgumentException: An item with the same key has already been added.
✅ 해결 방법
var dict = users
.GroupBy(u => u.Email)
.Select(g => g.First())
.ToDictionary(u => u.Email);
→ Dictionary 생성 전에 Email 중복을 제거하면 오류가 발생하지 않는다.
5. EqualityComparer로 중복 제거
.NET 6 이전 환경이나, 복잡한 비교 기준이 필요할 때 직접 IEqualityComparer<T>
를 구현하여 중복 제거할 수 있다.
public class EmailComparer : IEqualityComparer<User>
{
public bool Equals(User x, User y) => x.Email == y.Email;
public int GetHashCode(User obj) => obj.Email.GetHashCode();
}
var distinctUsers = users.Distinct(new EmailComparer());
→ Email 기준으로 중복된 사용자가 제거된다.
6. Select().Distinct() 활용
특정 속성만 추출해서 중복 없이 리스트로 만들고 싶을 때는 Select()
후 Distinct()
조합을 사용한다.
var emails = users.Select(u => u.Email).Distinct();
📌 출력 결과
test@example.com
user@example.com
→ 전체 사용자 중 중복되지 않는 Email만 추출된다.
💡 UI 바인딩용 익명 객체로 가공
var distinctEmails = emails.Select(e => new { Email = e });
→ ViewModel이나 JSON 응답용으로 활용할 수 있다.
7. 마무리
중복 제거는 단순해 보여도, 특정 조건을 유지하며 제거하려면 여러 가지 방법을 사용할 수 있다.
- Distinct(): 전체 객체 기준 중복 제거
- DistinctBy(): 특정 속성 기준 중복 제거 (.NET 6 이상)
- GroupBy + OrderBy + First(): 조건 유지하며 중복 제거
- ToDictionary: 중복 키 오류는 GroupBy로 해결
- EqualityComparer: 커스텀 기준 구현 가능
- Select().Distinct(): 특정 속성만 추출하여 중복 제거
실무에서는 상황에 따라 다양한 방법을 조합해 사용한다. 예를 들어, 회원 리스트에서 같은 Email 중 가장 먼저 가입한 사용자만 남기거나, Dictionary로 변환할 때 중복 키 오류를 피하기 위해 GroupBy 후 처리하는 방식 등이 있다.
📌 다음 편 예고
다음 글에서는 LINQ의 정렬 + 조건 필터 조합과 MaxBy()
, MinBy()
사용법을 정리해볼 예정이다.