una saber recorrer obtener lista existe elementos elemento colecciones buscar agregar c# linq list lambda

c# - saber - ¿Cómo puedo obtener cada enésimo elemento de una lista<T>?



recorrer una lista string c# (9)

Creo que si proporciona una extensión linq, debería poder operar en la interfaz menos específica, por lo tanto, en IEnumerable. Por supuesto, si está buscando velocidad, especialmente para N grandes, puede proporcionar una sobrecarga para el acceso indexado. Este último elimina la necesidad de iterar sobre grandes cantidades de datos no necesarios, y será mucho más rápido que la cláusula Where. Al proporcionar ambas sobrecargas, el compilador puede seleccionar la variante más adecuada.

public static class LinqExtensions { public static IEnumerable<T> GetNth<T>(this IEnumerable<T> list, int n) { if (n < 0) throw new ArgumentOutOfRangeException("n"); if (n > 0) { int c = 0; foreach (var e in list) { if (c % n == 0) yield return e; c++; } } } public static IEnumerable<T> GetNth<T>(this IList<T> list, int n) { if (n < 0) throw new ArgumentOutOfRangeException("n"); if (n > 0) for (int c = 0; c < list.Count; c += n) yield return list[c]; } }

Estoy usando .NET 3.5 y me gustaría poder obtener cada * n * ésimo elemento de una lista. No me molesta si se logra usando una expresión lambda o LINQ.

Editar

Parece que esta pregunta provocó bastante debate (lo cual es bueno, ¿no?). Lo principal que aprendí es que cuando crees que sabes todas las formas de hacer algo (incluso tan simple como esto), ¡piénsalo de nuevo!


En bucle

for(int i = 0; i < list.Count; i += n) //Nth Item..


Imho, ninguna respuesta es correcta. Todas las soluciones comienzan desde 0. Pero quiero tener el verdadero elemento enésimo

public static IEnumerable<T> GetNth<T>(this IList<T> list, int n) { for (int i = n - 1; i < list.Count; i += n) yield return list[i]; }


No estoy seguro de si es posible hacerlo con una expresión LINQ, pero sé que puede usar el método de extensión Where para hacerlo. Por ejemplo, para obtener cada quinto elemento:

List<T> list = originalList.Where((t,i) => (i % 5) == 0).ToList();

Esto obtendrá el primer elemento y cada quinto desde allí. Si desea comenzar en el quinto elemento en lugar del primero, compare con 4 en lugar de comparar con 0.


Puede usar la sobrecarga Where, que pasa el índice junto con el elemento

var everyFourth = list.Where((x,i) => i % 4 == 0);


Sé que es "vieja escuela", pero ¿por qué no usar simplemente un ciclo for con step = n?


Suena como

IEnumerator<T> GetNth<T>(List<T> list, int n) { for (int i=0; i<list.Count; i+=n) yield return list[i] }

Haría el truco. No veo la necesidad de usar Linq o expresiones lambda.

EDITAR:

Hazlo

public static class MyListExtensions { public static IEnumerable<T> GetNth<T>(this List<T> list, int n) { for (int i=0; i<list.Count; i+=n) yield return list[i]; } }

y escribes de una manera LINQish

from var element in MyList.GetNth(10) select element;

2da Edición :

Para hacerlo aún más LINQish

from var i in Range(0, ((myList.Length-1)/n)+1) select list[n*i];


private static readonly string[] sequence = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15".Split('',''); static void Main(string[] args) { var every4thElement = sequence .Where((p, index) => index % 4 == 0); foreach (string p in every4thElement) { Console.WriteLine("{0}", p); } Console.ReadKey(); }

salida


return list.Where((x, i) => i % nStep == 0);