Readable C# equivalent of Python slice operation

34,725

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 }
Share:
34,725

Related videos on Youtube

LJNielsenDk
Author by

LJNielsenDk

GitLab LinkedIn profile Upwork profile

Updated on July 09, 2022

Comments

  • LJNielsenDk
    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 slicing to the point of it not obviously answering the question.

  • Seng Cheong
    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
    LJNielsenDk over 10 years
    I 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
    HaveNoDisplayName over 8 years
    Add explanation to your answer
  • Necronomicron
    Necronomicron almost 8 years
    While the answer is very helpful, example is totally wrong except 2nd line. I've suggested an edit.
  • kazuoua
    kazuoua over 7 years
    This solution is incomplete as it doesn't support negative indexes (e.g., [-5:-4]).
  • Jabba
    Jabba about 6 years
    Does it support negative indexing? Python does.
  • BHC
    BHC almost 5 years
    LINQ SklpLast and TakeLast methods imitate negative indexes.
  • LeBigCat
    LeBigCat almost 5 years
    No, take is obviously > 0, Skip also if you take a look at his description. You can strill pass negative without got any exception.
  • NetMage
    NetMage about 3 years
    List<T> does not implement indexing with Range and the Range pattern requires a member named Slice and sadly doesn't support extension methods.