2010-01-24 2 views
8

클래스라는 Item이 있습니다. Item에는 문자열 인 ItemCode라는 식별자 속성이 있습니다. 항목 목록에있는 모든 별개의 항목 목록을 얻고 싶습니다.IEnumerable에서 비 구분 요소 가져 오기

예 :

List<Item> itemList = new List<Item>() 
{ 
    new Item("code1", "description1"), 
    new Item("code2", "description2"), 
    new Item("code2", "description3"), 
}; 

내가 아래 두 항목 내가
var distinctItems = itemsList.Distinct(); 

내가 대단한 별개 항목의 목록을 사용하는 경우

을 포함하는 목록을 원하지만 내가 원하는 거의 반대입니다. 원본 목록에서 뚜렷한 목록을 뺄 수는 있지만 모든 반복을 포함하지는 않을 것입니다. 각각의 반복은 하나만 포함됩니다.

나는 놀이를했고 우아한 해결책을 알아낼 수 없다. 모든 포인터 또는 도움을 많이 주시면 감사하겠습니다. 감사!

내가 3.5이 그렇게 LINQ는

답변

11

필자의 의견 :

var distinctItems = 
    from list in itemsList 
    group list by list.ItemCode into grouped 
    where grouped.Count() > 1 
    select grouped; 
+0

감사합니다. magnus (와 Thomas)와 저는 GroupBy를 사용하지 않을 것입니다. – RichK

2

당신은 운영자에 의해 그룹을 시도 할 수도 있습니다. 아이디어는 그룹 그들에게 ItemCode하여 하나 명 이상의 멤버 그룹을 복용 같은 것을하는 것입니다 :

var grouped = from i in itemList 
       group i by i.ItemCode into g 
       select new { Code = g.Key, Items = g }; 

var result = from g in grouped 
      where g.Items.Count() > 1; 
+0

나는이 컴파일을 얻을 수 없습니다. 'group by'과 'into'문에 대해 신음합니다. – RichK

+0

그룹과 "i"사이의 "i"를 잊어 버렸습니다. $ 이제 고정되었지만 magnus가 썼던 것과 본질적으로 같습니다. –

0

나는 사용자 정의 확장 방법을 쓰는 게 좋을 것,

static class RepeatedExtension 
{ 
    public static IEnumerable<T> Repeated<T>(this IEnumerable<T> source) 
    { 
     var distinct = new Dictionary<T, int>(); 
     foreach (var item in source) 
     { 
      if (!distinct.ContainsKey(item)) 
       distinct.Add(item, 1); 
      else 
      { 
       if (distinct[item]++ == 1) // only yield items on first repeated occurence 
        yield return item; 
      }      
     } 
    } 
} 

Item 클래스에 대해 Equals() 메서드를 재정 의하여 아이템이 코드별로 올바르게 비교되어야합니다. 확장 방법으로

11

:

public static IEnumerable<T> NonDistinct<T, TKey> (this IEnumerable<T> source, Func<T, TKey> keySelector) 
{ 
    return source.GroupBy(keySelector).Where(g => g.Count() > 1).SelectMany(r => r); 
} 
+0

깨끗하고 매우 재사용 할 수있는 감사합니다! – crabCRUSHERclamCOLLECTOR

관련 문제