J'ai un IEnumerable et je veux obtenir un nouvel IEnumerable contenant tous les nième éléments.Prendre tous les deuxièmes objets de la liste
Est-ce que cela peut être fait dans Linq?
J'ai un IEnumerable et je veux obtenir un nouvel IEnumerable contenant tous les nième éléments.Prendre tous les deuxièmes objets de la liste
Est-ce que cela peut être fait dans Linq?
Juste pensé à elle ... moi
La méthode IEnumerable<T>.Where()
a une surcharge qui prend l'indice de l'élément courant - exactement ce que le médecin a ordonné.
(new []{1,2,3,4,5}).Where((elem, idx) => idx % 2 == 0);
Ce retournerait
{1, 3, 5}
Mise à jour: Afin de couvrir à la fois mon cas d'utilisation et la suggestion de Dan Tao, Précisons aussi ce que le premier élément retourné doit être:
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);
... reviendrait
{2, 4}
Pour mettre en œuvre 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);
}
Utilisation:
var upToTen = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var evens = upToTen.Sample(2);
var multiplesOfThree = upToTen.Sample(3);
Vous pouvez également passer le tableau et utiliser 'Enumerable.Range (1,10)'. –
@Anthony: C'est juste un exemple, destiné à la compréhension immédiate. Je sais que certains développeurs devraient rechercher 'Enumerable.Range'. –
Sans LINQ, vous pouvez également créer une méthode d'extension avec 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;
}
}
}
Envelopper dans un 'using'! ('IEnumerable' hérite de' IDisposable'.) –
@Dan: Vous voulez dire IEnumerator. Comment se fait-il que je n'ai jamais réalisé cela auparavant?
Oui, je voulais dire 'IEnumerator'. Oups! (Pour une raison quelconque, je tape toujours un quand je veux taper l'autre .. Doit être de la mémoire musculaire.) –
Première fois que j'ai vu une utilisation vraiment solide pour l'index dans un prédicat de collection, bravo, je n'aurais pas pensé à ça. –
Vous pouvez définir une méthode d'extension qui renvoie this.Where (...) pour le rendre plus clair dans votre application elle-même. – Douglas
Je pourrais suggérer d'utiliser 'idx + 1' pour correspondre à la description de" chaque Nième élément "; au moins pour moi, cela suggère que le premier élément renvoyé devrait être le Nième élément. Donc, tous les deuxièmes éléments dans '{1,2,3,4,5}' - to * me * - signifient '{2,4}' (votre code renvoie '{1,3,5}'). Peut-être que c'est subjectif, cependant. –