140 votes

Vérifier si un IEnumerable contient tous les éléments d'un autre IEnumerable

Quel est le moyen le plus rapide de déterminer si un IEnumerable contient tous les éléments d’un autre IEnumerable lors de la comparaison d’un champ / d’une propriété de chaque élément des deux collections?


 public class Item
{
    public string Value;

    public Item(string value)
    {
        Value = value;
    }
}

//example usage

Item[] List1 = {new Item("1"),new Item("a")};
Item[] List2 = {new Item("a"),new Item("b"),new Item("c"),new Item("1")};

bool Contains(IEnumerable<Item> list1, IEnumerable<Item>, list2)
{
    var list1Values = list1.Select(item => item.Value);
    var list2Values = list2.Select(item => item.Value);

    return //are ALL of list1Values in list2Values?
}

Contains(List1,List2) // should return true
Contains(List2,List1) // should return false
 

179voto

Kent Boogaart Points 97432

Il n'y a pas de "voie rapide" pour ce faire, à moins que vous suivre et de maintenir un certain état qui détermine si toutes les valeurs dans une seule collection sont contenus dans un autre. Si vous n'avez qu' IEnumerable<T> contre, je voudrais utiliser Intersect.

var allOfList1IsInList2 = list1.Intersect(list2).Count() == list1.Count();

Le rendement de ce qui devrait être très raisonnable, car Intersect() énumérer sur chaque liste, juste une fois. Aussi, le deuxième appel à Count() sera optimale si le type sous-jacent est un ICollection<T> plutôt que juste un IEnumerable<T>.

117voto

J W Points 173

Vous pouvez également utiliser Except pour supprimer de la première liste toutes les valeurs figurant dans la deuxième liste, puis vérifier si toutes les valeurs ont été supprimées:

 var allOfList1IsInList2 = !list1.Except(list2).Any();
 

Cette méthode avait l'avantage de ne pas nécessiter deux appels à Count ().

33voto

John K Points 13695

C # 3.5+

Utilisation de Enumerable.All<TSource> pour déterminer si tous les éléments de List2 sont contenus dans List1:

 bool hasAll = list2Uris.All(itm2 => list1Uris.Contains(itm2));
 

Cela fonctionnera également lorsque list1 contient même plus que tous les éléments de list2.

1voto

bkaid Points 29335

SequenceEqual, l'opérateur Linq, fonctionne également (mais est sensible au fait que les éléments énumérables soient dans le même ordre)

 return list1Uris.SequenceEqual(list2Uris);
 

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