I have a collection, specifically an IList<T>
. I know two elements within the collection, startElement
and endElement
.
Is there a LINQ query that will return the enumerable from startElement
to endElement
, inclusive?
I thought about using sequence.SkipWhile(p=>p!=startElement).TakeWhile(q=>q!=endElement)
but that misses out the last element...
This doesn't use LINQ, but it's probably the most straightforward/readable approach.
int startIndex = sequence.IndexOf(startElement),
endIndex = sequence.IndexOf(endElement);
var range = sequence.GetRange(
startIndex,
// +1 to account for zero-based indexing
1 + endIndex - startIndex
);
Note that this is technically less efficient than alternatives, but if you already have an IList in memory, the differences will likely be less than a millisecond which is a small sacrifice to make for readable code.
I'd recommend wrapping the code block with a Stopwatch to test against your specific situation to be sure, however.
This will be the most efficient, as it doesn't create any unnecessary enumerator objects and only traverses the list one time.
var result = new List<T>();
var inSequence = false;
for (var i = 0; i < list.Length; i++)
{
var current = list[i];
if (current == startElement) inSequence = true;
if (!inSequence) continue;
result.add(current);
if (current == endElement) break;
}
This won't handle the case where endElement
is missing, but you could do that pretty easily by assigning result = null
as the last line of the for
loop where i = list.Length - 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With