Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Array.Slice Method #42140

Closed
osamakawish opened this issue Sep 11, 2020 · 2 comments
Closed

Array.Slice Method #42140

osamakawish opened this issue Sep 11, 2020 · 2 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Runtime

Comments

@osamakawish
Copy link

Background and Motivation

Purpose: Simplify array slicing. I know this is done in ArraySegment. I'm not sure as to why a roundabout method (ie. by switching types entirely) is used. As much as it can be done simply on the side, array slicing is a very useful feature to have.

The problem with ArraySegment is that it converts to a completely separate type, only to have to be converted back to an array.

To put it simply, C#'s implementation of array slicing is very counter-intuitive. And something as essential as array slicing shouldn't have such a complex implementation.

Proposed API

namespace System.Collections.Generic
{
    public class Array<T> {
...
+    public static Array<T> Slice(int start, int end);
+    public static Array<T> this[int start, int end] => Slice(start, end);
...    
    }
}

Usage Examples

int[] arr = new int[6] { 12, 54, -8, 0, 201, -122 };
int[] sl1 = arr.Slice(1, 4); /* { 54, -8, 0 } */
Console.WriteLine(arr[3,5]); /* { 0, 201 }

Alternative Designs

As I said, this is straightforward to implement on your own, as it simply requires defining the method:

T[] slice<T>(this Array<T> arr, int start, int end) {
    int len = end - start;
    int[] sliced = new int[len];
    for(int i=0; i<len; i++) {
        sliced[i] = arr[start + i];
    }
    return sliced;
}

However, as straightforward as this is, having it as a native part of the language would be very convenient, since array slicing occurs often. Additional note: it may also be implemented as part of IEnumerable.

Python offers simple notation for this too, and I'm not sure of other languages that provide simple notation for slicing arrays.

I looked into ArraySegment, but again, switching to a separate type entirely for a simple task is inconvenient. Not even having a method for slicing at all makes little sense. I believe there's a variant of the Array<T>.Copy method that pulls it off, but for something as simple as a slice, it requires digging through several different call variations to get the right one, which again, seems unnecessary for such an essential programming feature.

Again, the this[int start, int end] is an optional simplification. But a Slice(int start, int end) method would be well appreciated.

Risks

If others have already defined the this[int, int] to implement a slice or something else, or a slice method of their own, it'll be overridden code. Besides that, there's obviously the IndexOutOfRange exception that might occur. I can't think of any risks other than that that wouldn't be present otherwise.

Thinking about risks of your own code is always a little difficult though. So feel free to mention anything else I haven't thought of.

@osamakawish osamakawish added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Sep 11, 2020
@GrabYourPitchforks
Copy link
Member

This is already implemented today.

public static class Program {
    public static void Main() {
        int[] arr = new int[] { 0, 1, 2, 3, 4 };
        int[] arr2 = arr[2..^1];
        foreach (var i in arr2)
        {
            Console.WriteLine(i);
        }
    }
}

Prints:

2
3

See also: https://github.com/dotnet/runtime/search?q=getsubarray

@huoyaoyuan
Copy link
Member

huoyaoyuan commented Sep 11, 2020

since array slicing occurs often

If you do slice array often, then you should use Memory or Span everywhere. I know there are many api not designed for spans, but arrays are not designed for slicing, neither.
ArraySegment was a historical design. It's covered by Memory.

@jkotas jkotas closed this as completed Sep 11, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 7, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Runtime
Projects
None yet
Development

No branches or pull requests

4 participants