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


¿Cuál es el equivalente en C# de las operaciones slice 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 a la pregunta.

Author: Community, 2013-12-19

5 answers

El 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));
 41
Author: Ben,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-23 18:41:45

Si tiene una List getRange puede ser útil.

Desde el enlace MSDN:

Una copia superficial de una colección de tipos de referencia, o un subconjunto de 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 apunta a los mismos objetos que las referencias en el lista original.

La función Slice puede ser:

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

Rangos negativos que python los soportes de corte también se pueden manipular con cierta pérdida de limpieza.

 4
Author: bashrc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-19 09:03:12

De esta manera no tienes que restar

public static IEnumerable<A> Slice<A> (int from, int to, IEnumerable<A> e) {
    return e.Take (to).Skip (from);
}
 2
Author: Cristian Garcia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-03 19:43:26
public static T[] slice<T>(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;
}
 1
Author: Maurits van Riezen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-06 09:25:55

Escribe una extensión personalizada:

public static List<T> Slice<T>(this List<T> 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<char> {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
    Assert.Equal(new List<char> {'c', 'd'}, li1.Slice(2, 4));
    Assert.Equal(new List<char> {'b', 'c', 'd', 'e', 'f', 'g'}, li1.Slice(1, li1.Count));
    Assert.Equal(new List<char> {'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<char>(), li1.Slice(100, 200));

    Assert.Equal(new List<char> {'g'}, li1.Slice(-1, li1.Count));
    Assert.Equal(new List<char> {'f', 'g'}, li1.Slice(-2, li1.Count));
    Assert.Equal(new List<char> {'a', 'b', 'c', 'd', 'e', 'f'}, li1.Slice(0, -1));

    Assert.Equal(new List<char> {'c', 'd', 'e'}, li1.Slice(2, -2));
}
 0
Author: Jabba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-05 10:44:39