How can I achieve the equivalent of
// myList is a List<T>
myList = myList.GetRange(offset, number);
as an in-place statement? (i.e. without creating a new list in the process)
CodePudding user response:
without creating a new list
How about enumerating the result of a LINQ Skip/Take:
myList.Skip(offset).Take(number);
If you're looking to make permanent alterations to the list:
myList.RemoveRange(offset number, myList.Count - (offset number));
myList.RemoveRange(0, offset);
You might find that it's faster to make a new list than remove from an existing one; if you're doing this for performance reasons, be sure to race your horses
CodePudding user response:
Not really possible due to how List handles its internal array. Another "problem" is that the new List would have Add, Remove etc. How would those affect the original List?
Depending on how this new "slice" is to be used... maybe an IReadOnlyList facade would be appropriate?
Inject the List, Offset, Number. Implement the methods using the args to offset into the inner List indexer... (with protections for the range being greater than List.Count etc)
You'd need to implement an enumerator with the same offset, but that's pretty easy with yield
CodePudding user response:
Or...
CollectionsMarshal.AsSpan(myList).Slice(offset, number);
will give you a Span over the internal array. This has an enumerator, indexer, count.
Still need to take care that offset range is not greater than Capacity. And it'll get "tricky" if the Capacity of the List changes to intersect the span. As List will create a new array, but your span will still be over the old one.
Another "careful what you wish for" situation :)
CodePudding user response:
A simpler approach to update the list in-place:
myList.RemoveRange(0, offset); // Remove items at the beginning
myList.RemoveRange(count, myList.Count - count); // Remove items at the end
This has O(n)
complexity, where n
= myList.Count - count
.