Frage

Gibt es eine gute Möglichkeit, durch eine Teilmenge von einer Sammlung in C # nur aufzuzählen? Das heißt, ich habe eine Sammlung von einer großen Anzahl von Objekten (etwa 1000), aber ich mag nur aufzuzählen, durch die Elemente 250 - 340. Gibt es einen guten Weg, um einen Enumerator für eine Teilmenge der Sammlung zu erhalten, ohne mit einer anderen Sammlung?

Edit:. Sollte, dass dies erwähnt wird mit .NET Framework 2.0

War es hilfreich?

Lösung

Versuchen Sie, die folgende

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

Oder allgemein

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

Bearbeiten 2.0 Lösung

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

Andere Tipps

Ich mag es einfach zu halten (wenn Sie den Enumerator nicht unbedingt brauchen):

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

Die Anpassung Jareds Original-Code für .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;
    }
}

Und es zu verwenden:

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

einmal Anpassung Jarad den Code wieder, wird diese Erweiterung Methode Sie eine Teilmenge erhalten, die von definiert ist Punkt , nicht indizieren.

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

Das könnte Sie der Lage sein, etwas mit Linq zu tun. Die Art, wie ich dies tun würde, ist die Objekte in einem Array zu setzen, dann kann ich wählen, welche Elemente, die ich auf der Grundlage der Array-ID verarbeiten möchten.

Wenn Sie feststellen, dass Sie eine angemessene Menge häppchen von Listen und Sammlungen zu tun, könnte es sich lohnen, die Lernkurve in Klettern die C5 Allgemein Sammlung Bibliothek .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top