2010-07-13 5 views
7

개체를 나타내는 간단한 클래스가 있습니다. 그것은 5 개의 속성 (날짜, 2 개의 소수, 정수 및 문자열)을가집니다. 나는 CollectionBase에서 파생 된 컬렉션 클래스를 가지고 있는데 이는 첫 번째 클래스의 여러 객체를 유지하기위한 컨테이너 클래스입니다.LINQ를 사용하여 컬렉션에서 중복 개체를 찾아 제거하는 방법은 무엇입니까?

제 질문은 중복되는 개체 (예 : 날짜가 같고 소수 자릿수가 같고 정수가 같고 문자열이 같은 개체)를 제거하고 싶습니다. 중복을 찾아서 제거하기 위해 작성할 수있는 LINQ 쿼리가 있습니까? 또는 최소한 그들을 찾아야합니까?

답변

10

Distinct 연산자를 사용하여 중복을 제거 할 수 있습니다.

두 가지 오버로드가 있습니다. 하나는 사용자 유형에 대해 기본 동일성 비교자를 사용합니다 (사용자 정의 유형은 해당 유형에 Equals() 메소드를 호출 함). 두 번째 방법은 자신 만의 평등 비교자를 제공 할 수 있습니다. 둘 다 새 시퀀스을 원래 세트로 나타내며 중복되지 않습니다. 오버로드가 실제로 초기 컬렉션을 수정하지 않습니다. 둘 다 중복을 제외하는 새로운 시퀀스를 반환합니다.. 그냥 중복을 찾으려면

, 당신은 그렇게 할 GroupBy를 사용할 수 있습니다

var groupsWithDups = list.GroupBy(x => new { A = x.A, B = x.B, ... }, x => x) 
         .Where(g => g.Count() > 1); 

IList<> 같은에서 중복을 제거하기 위해 당신이 할 수 있습니다 :

yourList.RemoveAll(yourList.Except(yourList.Distinct())); 
+0

내 컬렉션이나 LINQ 쿼리에서만 제거 할 수 있습니까? – Icemanind

+0

LINQ 확장 메서드는 새로운 항목 집합을 만들고 원래 컬렉션은 그대로 유지됩니다. –

+0

모든 정보 주셔서 감사합니다! – Icemanind

4

당신의 간단한 경우 클래스는 사용자의 요구 사항을 충족하는 방식으로 Equals을 사용합니다. 그런 다음 고유 한 방법을 사용할 수 있습니다.

그렇다면 IEqualityComparer<T>의 인스턴스를 제공하여 원하는 방식으로 값을 비교해야합니다. (간결함을 무시 널 문제)

public class MyTypeComparer : IEqualityComparer<MyType> { 
    public bool Equals(MyType left, MyType right) { 
    return left.Name == right.Name; 
    } 
    public int GetHashCode(MyType type) { 
    return 42; 
    } 
} 

var noDupes = col.Distinct(new MyTypeComparer()); 

참고 예를 들어 GetHashCode에 대한 상수의 사용은 의도적이다. MyType의 의미에 대한 자세한 내용을 알지 못하면 효율적이고 올바른 해싱 기능을 작성할 수 없습니다. 효율적인 해싱 함수 대신에 유형의 의미에 상관없이 올바른 상수를 사용했습니다.

+0

그래도 내 컬렉션에서 제거 할 수 있습니까? 아니면 그냥 LINQ 쿼리? – Icemanind

+0

@icemanind 중복이없는 새 컬렉션을 반환합니다. 그 자리에서 컬렉션을 수정하지 않습니다. – JaredPar

+1

우수한 우수 사례 – danielea

관련 문제