Ich bin ziemlich glücklich mit der folgenden Methode. Es benötigt eine Aufzählung und eine Liste von sortierten, disjunkten Bereichen und überspringt Objekte, die nicht in den Bereichen liegen. Wenn die Bereiche Null sind, gehen wir einfach jeden Gegenstand. Die Aufzählung und die Liste der Bereiche sind beide möglicherweise groß. Wir möchten, dass diese Methode so leistungsstark wie möglich ist.Kann jemand eine bessere Version dieses Enumerators finden?
Kann jemand an ein eleganteres Stück Code denken? Ich bin hauptsächlich an C# -Implementierungen interessiert, aber wenn jemand eine dreistellige APL-Implementierung hat, ist das auch cool.
public static IEnumerable<T> WalkRanges<T>(IEnumerable<T> source, List<Pair<int, int>> ranges)
{
Debug.Assert(ranges == null || ranges.Count > 0);
int currentItem = 0;
Pair<int, int> currentRange = new Pair<int, int>();
int currentRangeIndex = -1;
bool betweenRanges = false;
if (ranges != null)
{
currentRange = ranges[0];
currentRangeIndex = 0;
betweenRanges = currentRange.First > 0;
}
foreach (T item in source)
{
if (ranges != null) {
if (betweenRanges) {
if (currentItem == currentRange.First)
betweenRanges = false;
else {
currentItem++;
continue;
}
}
}
yield return item;
if (ranges != null) {
if (currentItem == currentRange.Second) {
if (currentRangeIndex == ranges.Count - 1)
break; // We just visited the last item in the ranges
currentRangeIndex = currentRangeIndex + 1;
currentRange = ranges[currentRangeIndex];
betweenRanges = true;
}
}
currentItem++;
}
}
Dieser Code behandelt keine überlappenden Bereiche, z. gegebener Bereich (1,6) (4,8) sollten wir die Punkte 1..8 bekommen, aber die Punkte 1..6. Ist das Absicht? – Handcraftsman