318 votes

L’utilisation de Linq pour obtenir les derniers éléments de N d’une collection ?

É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 ?

477voto

kbrimington Points 14081
collection.Skip(Math.Max(0, collection.Count() - N)).Take(N);

68voto

James Curran Points 55356
<pre><code></code><p>Mise à jour : pour le problème de l’adresse clintp : un) en utilisant la méthode de TakeLast(), j’ai défini ci-dessus a résolu le problème, mais si vous voulez vraiment le faire sans la méthode supplémentaire, alors vous juste aurait-il à reconnaître la Enumerable.Reverse() peut être utilisé comme une méthode d’extension, vous ne sont pas tenus d’utiliser de cette façon :</p><pre><code></code></pre></pre>

53voto

Lasse V. Karlsen Points 148037

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;
    }
}

32voto

Mark Byers Points 318575

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.

11voto

Nick Babcock Points 1102

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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X