2012-06-29 3 views
-1

내가 중복 항목을 제거하기 위해 LINQ를 시도 :고유 항목으로 중복 된 항목이 제거되지 않습니까?

var MyItems = (from b in this.result 
       select new Item{ Name = b.Name, ID = b.ID }).Distinct(); 

(가) 내가 결과를 확인을, 그것은 중복 항목을 제거되지 않습니다. 이 문제를 해결하는 방법?

+2

중복 :

이를 확인하시기 바랍니다? Item에서 Equals를 오버라이드 했습니까? – Tudor

+2

이 컨텍스트에서 "Duplicate"를 정의하십시오 - 동일한 ID입니까? 평등 비교자를 제공해야 할 것입니다. –

+0

고마워요. 이제 Equals 및 GetHashCode 재정의 후 작업. – KentZhou

답변

1

일반 Distinct()은 기본 동등 비교자를 사용하여 컬렉션의 요소를 반환합니다.

이 사용자 정의 comparer를 사용할 수 있습니다

// modified example from docs, not tested 
class MyComparer : IEqualityComparer<Item> 
{ 
    // Items are equal if their ids are equal. 
    public bool Equals(Item x, Item y) 
    { 

     // Check whether the compared objects reference the same data. 
     if (Object.ReferenceEquals(x, y)) return true; 

     // Check whether any of the compared objects is null. 
     if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) 
      return false; 

     //Check whether the items properties are equal. 
     return x.ID == y.ID; 
    } 

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects. 

    public int GetHashCode(Product product) 
    { 
     //Check whether the object is null 
     if (Object.ReferenceEquals(item, null)) return 0; 

     //Get hash code for the ID field. 
     int hashProductId = product.ID.GetHashCode(); 

     return hashProductId; 
    } 

} 

var myItems = (from b in this.result 
       select new Item{ Name = b.Name, ID = b.ID }).Distinct(new MyComparer()); 
4

, Distinct()EqualityComparer<T>.Default를 사용하여, 다음과 같은 규칙이 있습니다 :

는 기본 같음 비교, 기본이 사용됩니다

IEqualityComparer을 포함 Distinct 재정에서보세요 IEquatable 제네릭 인터페이스를 구현하는 형식의 값을 비교합니다. 사용자 지정 데이터 형식을 비교하려면이 인터페이스를 구현하고 형식에 대한 고유 한 GetHashCode 및 Equals 메서드를 제공해야합니다.

귀하의 경우 ItemIEquatable<Item>을 구현해야합니다.

또는 IEqualityComparer<T>을 직접 가져 오는 overload of Distinct을 사용할 수 있습니다.

1

이 후 Items을 어떻게 사용하고 있는지 알 수 없으므로 여기에서 도박을하고 있습니다. 정말로 유일한 ID-이름 쌍을해야하는 경우

, 당신은 익명의 유형을 사용할 수 있습니다 무료로 비교 얻을 : 당신이 필요로하는 모든 이름-ID입니다

var MyItems = (from b in this.result 
       select new { b.Name, b.ID }).Distinct(); 
이 후

(다시 한 번 가정을 쌍), 결과 객체가있을 것이다 속성이 필요합니다

foreach(var item in MyItems) 
    Console.WriteLine("{0} -> {1}", item.ID, item.Name); 

C# Anonymous Types에 MSDN을 인용 :

익명 형식에 대한 Equals 및 GetHashCode 메서드는 속성의 같음 및 GetHashcode 메서드로 정의되므로 동일한 익명 형식의 인스턴스 두 개가 모두 해당 속성이 같은 경우에만 동일합니다.

2

당신은) (비교 자 객체 고유 전달할 수 있습니다 여기에

var MyItems = (from b in this.result 
      select new Item{ Name = b.Name, ID = b.ID }).Distinct(new ItemComparer()); 

사용자 지정 비교 자 클래스 당신은 목록에 새 항목을 추가해야합니다

// Custom comparer for the Item class 
class ItemComparer: IEqualityComparer<Product> 
{ 
    // Items are equal if their names and IDs are equal. 
    public bool Equals(Item x, Item y) 
    { 

     //Check whether the compared objects reference the same data. 
     if (Object.ReferenceEquals(x, y)) return true; 

     //Check whether any of the compared objects is null. 
     if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) 
      return false; 

    //Check whether the items' properties are equal. 
    return x.ID == y.ID && x.Name == y.Name; 
    } 

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects. 

    public int GetHashCode(Item item) 
    { 
     //Check whether the object is null 
     if (Object.ReferenceEquals(item, null)) return 0; 

     //Get hash code for the Name field if it is not null. 
     int hashItemName = item.Name == null ? 0 : item.Name.GetHashCode(); 

     //Get hash code for the ID field. 
     int hashItemID = item.ID.GetHashCode(); 

     //Calculate the hash code for the item. 
     return hashItemName^hashItemID; 
    } 

} 
-4

를 사용 foreach는 시험의 예입니다 :

foreach(var _item in result.Distinct()){ 
//Code here 
} 

ok :)

+0

Not OK :(........ –

+0

너는 운이 좋다. 나에게 좋다. –

관련 문제