2 votes

C# Linq Vérifier si une liste de liste est à l'intérieur d'une liste de liste

J'ai deux Listes de Listes :
(1) variantes et (2) options .

J'ai besoin de voir si TOUTES les options existent dans les variantes (indépendamment de l'ordre).

Par exemple, dans le code ci-dessous, je dois m'assurer que chaque liste d'éléments apparaît dans la liste des variantes. Ainsi, les listes "bleu", "rouge" et "vert" doivent apparaître dans la liste des variantes, quel que soit leur ordre.

EDIT (clarification) : Toutes les listes contenues dans "options" doivent apparaître dans "variants". Si l'une d'entre elles échoue, le booléen doit renvoyer false.

J'ai configuré une condition LINQ mais je ne sais pas pourquoi elle ne fonctionne pas. Toute aide serait appréciée.

 //TEST 1

    List<List<string>> variants = new List<List<string>>();
    variants.Add(new List<string> {"cars", "boats", "planes"});
    variants.Add(new List<string> {"money", "trees", "plants"});
    variants.Add(new List<string> {"green", "blue", "red" });
    variants.Add(new List<string> {"kid", "adult", "senior"});
    variants.Add(new List<string> {"tax", "insurance", "salary"});

    List<List<string>> options = new List<List<string>>();
    options.Add(new List<string> { "senior", "adult", "kid" });
    options.Add(new List<string> { "blue", "red", "green"});
    options.Add(new List<string> {"money", "trees", "plants"});

    bool exists = variants.Any(a => options.Any(b => b.SequenceEqual(a.OrderBy(x => x))));

    Console.WriteLine(exists);
    // The result should be TRUE even though the order of "senior", "adult" and "kid"
    // is different and that the order of listed items is different

 //TEST 2
    List<List<string>> options2 = new List<List<string>>();
    options2.Add(new List<string> { "senior", "adult", "kid" });
    options2.Add(new List<string> { "orange", "red", "green"});
    options2.Add(new List<string> {"money", "trees", "plants"});

    exists = variants.Any(a => options2.Any(b => b.SequenceEqual(a.OrderBy(x => x))));

    Console.WriteLine(exists);
    // The result should be FALSE. All listed options are TRUE except that the 2nd list has
    // "orange" which doesn't appear in the variants list.

 //TEST 3
    List<List<string>> options3 = new List<List<string>>();
    options3.Add(new List<string> { "senior", "red", "adult" });
    options3.Add(new List<string> { "blue", "kid", "green"});
    options3.Add(new List<string> {"money", "trees", "plants"});

    exists = variants.Any(a => options3.Any(b => b.SequenceEqual(a.OrderBy(x => x))));

    Console.WriteLine(exists);
    // The result should be FALSE. All of the items actually exist in the variant list, 
    // but "senior", "kid", and "adult" do not appear together within a list of variants.

3voto

vc 74 Points 15694

Vous pouvez construire un HashSet pour chaque liste de variantes et ensuite vérifier pour chaque liste d'options qu'au moins un ensemble de variantes contient toutes les options :

List<HashSet<string>> variantSets = variants.Select(vl => new HashSet<string>(vl)).ToList();

bool allIncluded = options.All(ol => variantSets.Any(vs => ol.All(vs.Contains)));

Lien vers le violon

3voto

Charles Mager Points 19603

Je vous suggère d'utiliser HashSet<T> plutôt que List<T> pour les options/variantes, car il s'agit ici d'une sémantique d'ensemble plutôt que d'une sémantique de liste : les options ne peuvent apparaître qu'une seule fois et l'ordre n'est pas important.

Par exemple :

 var variants = new List<HashSet<string>>();
 variants.Add(new HashSet<string> {"cars", "boats", "planes"});
 variants.Add(new HashSet<string> {"money", "trees", "plants"});
 variants.Add(new HashSet<string> {"green", "blue", "red" });
 variants.Add(new HashSet<string> {"kid", "adult", "senior"});
 variants.Add(new HashSet<string> {"tax", "insurance", "salary"});

Et votre contrôle est inversé : vous voulez vérifier si toutes les options correspondent à l'une des variantes. Vous devez donc commencer par les options. HashSet<T> possède une méthode permettant de vérifier si les ensembles sont égaux, vous pouvez donc l'utiliser :

bool exists = options.All(option => variants.Any(option.SetEquals));

2voto

MaxKlaxx Points 423

Votre code fonctionne jusqu'à présent, mais les deux listes devraient être triées dans la comparaison.

avant :

bool exists = variants.Any(a => options.Any(b => b.SequenceEqual(a.OrderBy(x => x))));

fixe :

bool exists = options.All(a => variants.Any(b => b.OrderBy(x => x).SequenceEqual(a.OrderBy(x => x))));

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