Readable C# equivalent of Python slice operation
Solution 1
The closest is really LINQ .Skip()
and .Take()
Example:
var result1 = myList.Skip(2).Take(2);
var result2 = myList.Skip(1);
var result3 = myList.Take(3);
var result4 = myList.Take(3).Concat(myList.Skip(4));
Solution 2
As of C#8
slicing becomes a lot easier for indexed data structures.
var result1 = myList[2..5]; // end (5) is exclusive
var result2 = myList[1..^0]; // from index 1 to the end
var result3 = myList[0..3]; // end (3) exclusive
Read more about Ranges and indices here and here.
Solution 3
If you have a List
GetRange can come in handy.
From MSDN link:
A shallow copy of a collection of reference types, or a subset of that collection, contains only the references to the elements of the collection. The objects themselves are not copied. The references in the new list point to the same objects as the references in the original list.
The Slice
function can then be:
public static IEnumerable<T> Slice<T>(this List<T> source, int from, int to) => source.GetRange(from, to - from);
Negative ranges that python slice supports can also be handled with some loss of cleanliness.
Solution 4
This way you don't have to subtract
public static IEnumerable<A> Slice<A> (int from, int to, IEnumerable<A> e) {
return e.Take (to).Skip (from);
}
Solution 5
Here's an extension:
public static IEnumerable<T> Slice<T>(this IEnumerable<T> source, int start = 0, int end = 0)
{
start = (start >= 0) ? start : source.Count() + start;
end = (end > 0) ? end : source.Count() + end;
return source.Skip(start).Take(end - start);
}
Examples:
var input = new[] { 0, 1, 2, 3, 4, 5, 6, 7 };
numbers.Slice(1, 4); // { 1, 2, 3 }
numbers.Slice(-3, -1); // { 5, 6 }
numbers.Slice(5); // { 5, 6, 7 }
numbers.Slice(end:-4); // { 0, 1, 2, 3 }
Related videos on Youtube
Comments
-
LJNielsenDk almost 2 years
What is the C# equivalent of Python slice operations?
my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] result1 = my_list[2:4] result2 = my_list[1:] result3 = my_list[:3] result4 = my_list[:3] + my_list[4:]
Some of it is covered here, but it is ugly
and doesn't address all the uses of slicingto the point of it not obviously answering the question.-
henon about 5 yearsI actually implemented Python-type slicing in ArraySlice<T>. Check it out: github.com/henon/SliceAndDice
-
-
Seng Cheong over 10 years+1 You beat me to the trickier examples while I was grabbing MSDN URLs :-) This one is yours. Might I suggest using
result1
,result2
to match the OP's examples? -
LJNielsenDk over 10 yearsI wish I could use Python (work project), but I guess I'll have to settle for this ugly stuff where I actually have to think when reading it.
-
HaveNoDisplayName over 8 yearsAdd explanation to your answer
-
Necronomicron almost 8 yearsWhile the answer is very helpful, example is totally wrong except 2nd line. I've suggested an edit.
-
kazuoua over 7 yearsThis solution is incomplete as it doesn't support negative indexes (e.g., [-5:-4]).
-
Jabba about 6 yearsDoes it support negative indexing? Python does.
-
BHC almost 5 yearsLINQ
SklpLast
andTakeLast
methods imitate negative indexes. -
LeBigCat almost 5 yearsNo, take is obviously > 0, Skip also if you take a look at his description. You can strill pass negative without got any exception.
-
NetMage about 3 years
List<T>
does not implement indexing withRange
and the Range pattern requires a member namedSlice
and sadly doesn't support extension methods.