2009-05-19 4 views
9

C#에서 컬렉션의 하위 집합을 통해 열거 할 수있는 좋은 방법이 있습니까? 즉, 많은 수의 개체 (예 : 1000)의 컬렉션이 있지만 요소 250-340을 통해 열거하고 싶습니다. 컬렉션의 하위 집합에 대한 열거자를 얻는 좋은 방법이 있습니까? 다른 콜렉션을 사용하고 있습니까?C#에서 Collection의 하위 집합을 통해 열거합니까?

편집 : .NET Framework 2.0을 사용하고 있다고 언급 했어야합니다.

답변

32

당신은 Linq에 뭔가를 할 수있을 수있는

var col = GetTheCollection(); 
var subset = col.Skip(250).Take(90); 

를 다음 또는 더 일반적으로

public static IEnumerable<T> GetRange(this IEnumerable<T> source, int start, int end) { 
    // Error checking removed 
    return source.Skip(start).Take(end - start); 
} 

편집 2.0 솔루션을

public static IEnumerable<T> GetRange<T>(IEnumerable<T> source, int start, int end) { 
    using (var e = source.GetEnumerator()){ 
    var i = 0; 
    while (i < start && e.MoveNext()) { i++; } 
    while (i < end && e.MoveNext()) { 
     yield return e.Current; 
     i++; 
    } 
    }  
} 

IEnumerable<Foo> col = GetTheCollection(); 
IEnumerable<Foo> range = GetRange(col, 250, 340); 
+0

그 확장 방법을 좋아합니다. –

+0

죄송합니다. .NET 2.0을 사용하고 있습니다. 건너 뛰기를 사용할 수 없습니다. 그것이 .NET 3.5에 있다면, 이것은 황금일 것입니다. –

+1

@McWafflestix는 2.0의 트릭을 수행하는 2.0 솔루션 – JaredPar

0

을보십시오. 이 작업을 수행하는 방법은 객체를 배열에 넣는 것입니다. 그런 다음 배열 ID를 기반으로 처리 할 항목을 선택할 수 있습니다.

0

목록 및 모음을 잘게 자르고 깎아야 할 필요가있는 경우 학습 곡선을 the C5 Generic Collection Library으로 등반 할 가치가 있습니다.

3

내가 간단하게 좋아 (당신이 반드시 열거 필요가없는 경우) : 닷넷 2.0 제라드의 원본 코드를 적응

for (int i = 249; i < Math.Min(340, list.Count); i++) 
{ 
    // do something with list[i] 
} 
+0

이것은 수락 된 답변보다 훨씬 간단합니다 ... 또한 내가 본 것처럼, 정말 큰 목록의 끝을 향하고있는 항목을 얻으려면 이점이 있습니다. 수락 된 대답은 처음부터 불필요하게 횡단합니다. ...이 모든 것을 고려해 볼 때, 왜이 답변에는 극소량의 상향 신호가 있는지 혼란 스럽습니다. 이 답변에 대한 기술적 인 내용이 누락 되었습니까? 아니면 다른 사람이 받아 들인 후에이 답변을 게시 한 경우 일 뿐이므로 실제로 많은 사람들이 그것을 보지 않았습니다. –

+0

@AmithGeorge 대부분의 다른 대답은 IEnumerable을 구현하는 모든 컬렉션에서 작동합니다. 이 대답은 IList 또는 다른 숫자 인덱서/아래 첨자를 구현하려는 사람에게만 사용됩니다. 나는 물건을 깨끗하게하기를 바란다. – CanadaIT

2

:

IEnumerable<T> GetRange(IEnumerable<T> source, int start, int end) 
{ 
    int i = 0; 
    foreach (T item in source) 
    { 
     i++; 
     if (i>end) yield break; 
     if (i>start) yield return item; 
    } 
} 

을 그리고 그것을 사용하기 :

foreach (T item in GetRange(MyCollection, 250, 340)) 
{ 
    // do something 
} 
1

자 라드의 코드를 다시 적용하면이 확장 방법을 사용하면 상품 번호, 색인 제외

//! Get subset of collection between \a start and \a end, inclusive 
    //! Usage 
    //! \code 
    //! using ExtensionMethods; 
    //! ... 
    //! var subset = MyList.GetRange(firstItem, secondItem); 
    //! \endcode 
class ExtensionMethods 
{ 
    public static IEnumerable<T> GetRange<T>(this IEnumerable<T> source, T start, T end) 
    { 
#if DEBUG 
     if (source.ToList().IndexOf(start) > source.ToList().IndexOf(end)) 
      throw new ArgumentException("Start must be earlier in the enumerable than end, or both must be the same"); 
#endif 
     yield return start; 

     if (start.Equals(end)) 
      yield break;             //start == end, so we are finished here 

     using (var e = source.GetEnumerator()) 
     { 
      while (e.MoveNext() && !e.Current.Equals(start));    //skip until start     
      while (!e.Current.Equals(end) && e.MoveNext())     //return items between start and end 
       yield return e.Current; 
     } 
    } 
} 
관련 문제