79 votes

Vérifier si tous les éléments sont identiques dans une liste

J'ai une liste d'éléments (de date à heure). Comment puis-je vérifier si tous les éléments sont identiques à l'aide d'une requête LINQ ? À tout moment, il peut y avoir 1, 2, 20, 50 ou 100 éléments dans la liste.

Merci

124voto

SLaks Points 391154

Comme ça :

if (list.Distinct().Skip(1).Any())

Ou

if (list.Any(o => o != list[0]))

(ce qui est probablement plus rapide)

26 votes

Potentiellement plus facile à lire avec "All" au lieu de "Any". Vous pouvez également utiliser First() au lieu de [0] si l'accès à la liste ne peut pas être effectué (IEnumerable). if (list.All(o => o == list.First()))) { ... }

2 votes

list.Distinct().Skip(1).Any() n'est pas différent de list.Distinct().Count != 1 n'est-ce pas ?

1 votes

@GraemeWicksted le but de Any() est d'être plus rapide si un élément est trouvé qui ne correspond PAS. Dans ce cas, vous arrêtez d'évaluer la liste. Ce qui est légèrement plus clair cependant, c'est !(list.Any(o => o != list[0])) ce qui est vrai si aucun élément n'est différent du premier, c'est-à-dire s'ils sont tous identiques.

14voto

MSkuta Points 262

J'ai créé une méthode d'extension simple principalement pour la lisibilité qui fonctionne sur n'importe quel IEnumerable.

if (items.AreAllSame()) ...

Et la mise en œuvre de la méthode :

    /// <summary>
    ///   Checks whether all items in the enumerable are same (Uses <see cref="object.Equals(object)" /> to check for equality)
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="enumerable">The enumerable.</param>
    /// <returns>
    ///   Returns true if there is 0 or 1 item in the enumerable or if all items in the enumerable are same (equal to
    ///   each other) otherwise false.
    /// </returns>
    public static bool AreAllSame<T>(this IEnumerable<T> enumerable)
    {
        if (enumerable == null) throw new ArgumentNullException(nameof(enumerable));

        using (var enumerator = enumerable.GetEnumerator())
        {
            var toCompare = default(T);
            if (enumerator.MoveNext())
            {
                toCompare = enumerator.Current;
            }

            while (enumerator.MoveNext())
            {
                if (toCompare != null && !toCompare.Equals(enumerator.Current))
                {
                    return false;
                }
            }
        }

        return true;
    }

1 votes

Joli ! Je me pose juste une question sur l'implémentation de la liste vide. Je ne suis pas sûr de supposer qu'une liste vide signifie que "tous sont identiques" - cela semble être un cas à gérer par le consommateur, donc je pense que je vais lancer si la liste est vide. "Les pommes sont-elles les mêmes ? Aucune idée, car il n'y a pas de pommes dans le panier".

9voto

VBorisoff Points 672

Ma variante :

var numUniques = 1;
var result = list.Distinct().Count() == numUniques;

1 votes

J'aime bien ça, c'est très lisible et ça montre l'intention par rapport à la solution skip1/any.

5voto

KungFury Points 31

C'est aussi une option :

 if (list.TrueForAll(i => i.Equals(list.FirstOrDefault())))

Il est plus rapide que if (list.Distinct().Skip(1).Any()) et se comporte de la même manière que if (list.Any(o => o != list[0])) Toutefois, la différence n'est pas significative, et je suggère donc d'utiliser la version la plus lisible.

4voto

jor Points 511

Version VB.NET :

If list.Distinct().Skip(1).Any() Then

Ou

If list.Any(Function(d) d <> list(0)) Then

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