Equivalente en C # legible de la operación de corte de Python

¿Cuál es el equivalente en C # de las operaciones de división de Python?

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:] 

Parte de esto está cubierto aquí , pero es feo y no aborda todos los usos del corte hasta el punto de que obviamente no responde la pregunta.

Lo más cercano es realmente LINQ .Skip() y .Take()

Ejemplo:

 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)); 

Si tienes una List GetRange puede ser útil.

Desde el enlace de MSDN:

Una copia superficial de una colección de tipos de referencia, o un subconjunto de esa colección, contiene solo las referencias a los elementos de la colección. Los objetos en sí no se copian. Las referencias en la nueva lista apuntan a los mismos objetos que las referencias en la lista original.

La función Slice puede ser:

 public static IEnumerable Slice(this List source, int from, int to) => source.GetRange(from, to - from); 

Los rangos negativos que los soportes de corte de python también pueden manejarse con cierta pérdida de limpieza.

A partir de C#8 segmentación se vuelve mucho más fácil para las estructuras de datos indexados .

 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 

Lea más sobre rangos e índices aquí y aquí .

De esta manera no tienes que restar.

 public static IEnumerable Slice (int from, int to, IEnumerable e) { return e.Take (to).Skip (from); } 
 public static T[] slice(T[] l, int from, int to) { T[] r = new T[to - from]; for (int i = from; i < to; i++) { r[i-from]=l[i]; } return r; } 

Escribe una extensión personalizada:

 public static List Slice(this List li, int start, int end) { if (start < 0) // support negative indexing { start = li.Count + start; } if (end < 0) // support negative indexing { end = li.Count + end; } if (start > li.Count) // if the start value is too high { start = li.Count; } if (end > li.Count) // if the end value is too high { end = li.Count; } var count = end - start; // calculate count (number of elements) return li.GetRange(start, count); // return a shallow copy of li of count elements } 

Algunas pruebas:

 [Fact] public void Slice_list() { var li1 = new List {'a', 'b', 'c', 'd', 'e', 'f', 'g'}; Assert.Equal(new List {'c', 'd'}, li1.Slice(2, 4)); Assert.Equal(new List {'b', 'c', 'd', 'e', 'f', 'g'}, li1.Slice(1, li1.Count)); Assert.Equal(new List {'a', 'b', 'c'}, li1.Slice(0, 3)); Assert.Equal(li1, li1.Slice(0, 4).Concat(li1.Slice(4, li1.Count))); Assert.Equal(li1, li1.Slice(0, 100)); Assert.Equal(new List(), li1.Slice(100, 200)); Assert.Equal(new List {'g'}, li1.Slice(-1, li1.Count)); Assert.Equal(new List {'f', 'g'}, li1.Slice(-2, li1.Count)); Assert.Equal(new List {'a', 'b', 'c', 'd', 'e', 'f'}, li1.Slice(0, -1)); Assert.Equal(new List {'c', 'd', 'e'}, li1.Slice(2, -2)); }