Étant donné une collection, y a-t-il un moyen d’obtenir les derniers éléments de N de cette collection ? Si il n’est pas une méthode dans le cadre, quelle serait la meilleure façon d’écrire une méthode d’extension pour cela ?
Réponses
Trop de publicités?Note: j'ai raté votre question titre qui dit à l'Aide de Linq, donc ma réponse ne l'est pas en fait, l'utilisation de Linq.
Si vous voulez éviter la mise en cache un non-lazy copie de l'intégralité de la collection, vous pouvez les écrire sur une méthode simple qui fait à l'aide d'une liste liée.
La méthode suivante va ajouter chaque valeur qu'il trouve dans la collection d'origine dans une liste chaînée, et de l'assiette de la liste vers le bas pour le nombre d'éléments requis. Parce qu'elle maintient la liste, paré à ce nombre d'éléments de l'intégralité du temps par itération à travers la collection, il ne conservera une copie d'au plus N éléments de la collection d'origine.
Il ne nécessite pas de connaître le nombre d'éléments dans la collection d'origine, ni de parcourir plus d'une fois.
Utilisation:
IEnumerable<int> sequence = Enumerable.Range(1, 10000);
IEnumerable<int> last10 = sequence.TakeLast(10);
...
Méthode d'Extension:
public static class Extensions
{
public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> collection,
int n)
{
if (collection == null)
throw new ArgumentNullException("collection");
if (n < 0)
throw new ArgumentOutOfRangeException("n", "n must be 0 or greater");
LinkedList<T> temp = new LinkedList<T>();
foreach (var value in collection)
{
temp.AddLast(value);
if (temp.Count > n)
temp.RemoveFirst();
}
return temp;
}
}
Voici une méthode qui fonctionne sur tout dénombrable, mais utilise le seul stockage temporaire d’o (n) :
Utilisation :
Il fonctionne en utilisant un tampon en anneau de taille N pour stocker les éléments comme il les voit, remplaçant les éléments anciens par des neuves. Lorsque la fin de l’énumérable est atteinte le tampon en anneau contient les derniers éléments de N.
Je suis surpris que personne n’a mentionné, mais SkipWhile a-t-il une méthode qui utilise l’index de l’élément.
L’avantage uniquement perceptible que cette solution présente sur les autres, c’est que vous pouvez avoir la possibilité d’ajouter un prédicat pour faire une requête LINQ plus puissante et performant, au lieu d’avoir deux opérations distinctes qui parcourent l’interface IEnumerable deux fois.