Languague/C# / / 2025. 4. 12. 08:00

[C# LINQ] 중복 제거하면서 조건 유지하기 – DistinctBy 사용법 & 중복 키 오류 해결 포함

300x250



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() 사용법을 정리해볼 예정이다.

300x250
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유