Enumerar um subconjunto de uma coleção em C #?

votos
11

Existe uma boa maneira para enumerar apenas um subconjunto de uma coleção em C #? Ou seja, eu tenho uma coleção de um grande número de objetos (por exemplo, 1000), mas eu gostaria de enumerar apenas os elementos 250 - 340. Existe uma boa maneira de obter um enumerador para um subconjunto da coleção, sem usando outro Collection?

Edit: deveria ter mencionado que isso é usando .NET Framework 2.0.

Publicado 19/05/2009 em 21:00
fonte usuário
Em outras línguas...                            


6 respostas

votos
34

Tente o seguinte

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

Ou, mais geralmente

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

EDIT Solução 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);
Respondeu 19/05/2009 em 21:01
fonte usuário

votos
3

Eu gosto de mantê-lo simples (se você não precisa necessariamente o enumerador):

for (int i = 249; i < Math.Min(340, list.Count); i++)
{
    // do something with list[i]
}
Respondeu 19/05/2009 em 21:08
fonte usuário

votos
2

Adaptação código original de Jared para .Net 2.0:

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;
    }
}

E usá-lo:

 foreach (T item in GetRange(MyCollection, 250, 340))
 {
     // do something
 }
Respondeu 19/05/2009 em 21:11
fonte usuário

votos
1

Adaptação código de Jarad, mais uma vez, este método extensão vai te dar um subconjunto que é definida pelo artigo , não índice.

    //! 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;
        }
    }
}
Respondeu 15/07/2015 em 11:41
fonte usuário

votos
0

Se você achar que você precisa fazer uma quantidade razoável de fatiamento de listas e coleções, pode valer a pena subir a curva de aprendizagem para o Generic Coleção Biblioteca C5 .

Respondeu 19/05/2009 em 21:05
fonte usuário

votos
0

Você pode ser capaz de fazer algo com Linq. A maneira que eu iria fazer isso é colocar os objetos em uma matriz, então eu posso escolher os itens que eu quero processar baseado na id matriz.

Respondeu 19/05/2009 em 21:02
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more