Tengo un IEnumerable y quiero obtener un nuevo IEnumerable que contenga cada enésimo elemento.Tome cada segundo objeto en la lista
¿Se puede hacer esto en Linq?
Tengo un IEnumerable y quiero obtener un nuevo IEnumerable que contenga cada enésimo elemento.Tome cada segundo objeto en la lista
¿Se puede hacer esto en Linq?
Sólo descubierto a mí mismo ...
El método IEnumerable<T>.Where()
tiene una sobrecarga que toma el índice del elemento actual - justo lo que recetó el doctor.
(new []{1,2,3,4,5}).Where((elem, idx) => idx % 2 == 0);
Esto volvería
{1, 3, 5}
Actualización: Con el fin de cubrir tanto mi caso de uso y la sugerencia de Dan Tao, también vamos a especificar lo que debe ser el primer elemento devuelto:
var firstIdx = 1;
var takeEvery = 2;
var list = new []{1,2,3,4,5};
var newList = list
.Skip(firstIdx)
.Where((elem, idx) => idx % takeEvery == 0);
... devolvería
{2, 4}
Para implementar Cristi's suggestion:
public static IEnumerable<T> Sample<T>(this IEnumerable<T> source, int interval)
{
// null check, out of range check go here
return source.Where((value, index) => (index + 1) % interval == 0);
}
Uso:
var upToTen = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var evens = upToTen.Sample(2);
var multiplesOfThree = upToTen.Sample(3);
También podría saltear la matriz y usar 'Enumerable.Range (1,10)'. –
@Anthony: es solo un ejemplo, destinado a la comprensión inmediata. Sé que algunos desarrolladores tendrían que buscar 'Enumerable.Range'. –
Aunque no LINQ también puede crear un método de extensión con yield
.
public static IEnumerable<T> EverySecondObject<T>(this IEnumerable<T> list)
{
using (var enumerator = list.GetEnumerator())
{
while (true)
{
if (!enumerator.MoveNext())
yield break;
if (enumerator.MoveNext())
yield return enumerator.Current;
else
yield break;
}
}
}
¡Envuelve eso en un 'uso'! ('IEnumerable' hereda' IDisposable'.) –
@Dan: Quiere decir IEnumerator. ¿Cómo es que nunca me había dado cuenta de eso antes?
Sí, quise decir 'IEnumerator'. ¡Ups! (Por algún motivo siempre escribo uno cuando me refiero a escribir el otro. Debe ser memoria muscular) –
Primera vez que he visto un uso realmente sólido para el índice en un predicado de colección, bravo, no lo hubiera pensado. –
Puede definir un método de extensión que devuelva esto. Donde (...) para que esto quede más claro en su aplicación. – Douglas
Podría sugerir el uso de 'idx + 1' para que coincida con la descripción de" cada elemento enésimo "; al menos para mí, esto sugiere que el primer elemento devuelto debería ser el enésimo elemento. Entonces, cada segundo elemento en '{1,2,3,4,5}' - a * me * - significa '{2,4}' (tu código devuelve '{1,3,5}'). Quizás esto es subjetivo, sin embargo. –