72 votes

LINQ : Déterminer si deux séquences qui contiennent exactement les mêmes éléments

J'ai besoin de déterminer si oui ou non deux ensembles qui contiennent exactement les mêmes éléments. L'ordre n'a pas d'importance.

Par exemple, ces deux tableaux doivent être considérés comme égaux:

IEnumerable<int> data = new []{ 3,5,6,9 };
IEnumerable<int> otherData = new []{ 6,5,9,3}

Un jeu ne peut pas contenir tous les éléments, qui ne sont pas dans l'autre.

Cela peut être fait en utilisant le haut-opérateurs de requête ? Et quel serait le moyen le plus efficace pour la mettre en œuvre, considérant que le nombre d'éléments peut varier de quelques centaines ?

123voto

Mehrdad Afshari Points 204872

Si vous voulez traiter les tableaux comme des "ensembles" et d'ignorer les doublons, vous pouvez utiliser HashSet<T>.SetEquals méthode:

var isEqual = new HashSet<int>(first).SetEquals(second);

Sinon, votre meilleur pari est probablement le tri de ces deux séquences de la même manière et à l'aide de SequenceEqual pour les comparer.

50voto

Joren Points 7911

Je suggère de tri à la fois, et en faire un élément de comparaison.

data.OrderBy(x => x).SequenceEqual(otherData.OrderBy(x => x))

Je ne suis pas sûr de la façon rapide de la mise en œuvre de l' OrderBy , mais si c'est un O(n log n) en quelque sorte comme vous vous attendez à l'totale de l'algorithme est O(n log n).

Pour certains cas, de données, vous pouvez l'améliorer en utilisant une implémentation personnalisée de OrderBy que, par exemple, utilise un comptage, de tri, de O(n+k), avec k la taille de la plage où les valeurs se trouvent.

7voto

Justin Grant Points 25644

Si vous pourriez avoir des doublons (ou si vous voulez une solution qui fonctionne mieux pour les répertorie plus), je voudrais essayer quelque chose comme ceci:

static bool IsSame<T>(IEnumerable<T> set1, IEnumerable<T> set2)
{
    if (set1 == null && set2 == null)
        return true;
    if (set1 == null || set2 == null)
        return false;

    List<T> list1 = set1.ToList();
    List<T> list2 = set2.ToList();

    if (list1.Count != list2.Count)
        return false;

    list1.Sort();
    list2.Sort();

    return list1.SequenceEqual(list2);
}

Mise à JOUR: oups, vous les gars sont à droite-- à l'Exception de la (des) solution ci-dessous des besoins de regarder des deux côtés avant de traverser la rue. Et c'est moche perf pour les longues listes. Ignorer la suggestion ci-dessous! :-)

Voici un moyen facile de le faire. Notez que cela suppose que les listes ont pas de doublons.

bool same = data.Except (otherData).Count() == 0;

0voto

Kobi Points 65357
  1. Tout d'abord, vérifiez la longueur. Si elles sont différentes, les décors sont différents.
  2. vous pouvez le faire data.Intersect(otherData);, et de vérifier la longueur est identique.
  3. OU, simplt trier les jeux, et d'itérer à travers eux.

-2voto

Blounty Points 2856
    IEnumerable<int> data = new []{ 3,5,6,9 };
    IEnumerable<int> otherData = new[] {6, 5, 9, 3};

    if(data.All(x => otherData.Contains(x)))
    {
        //Code Goes Here
    }

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