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 / propriété de chaque élément dans les 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
c#
.net
linq
ienumerable
Brandon Zacharie
la source
la source
Réponses:
Il n'y a pas de «moyen rapide» de le faire, sauf si vous suivez et maintenez un état qui détermine si toutes les valeurs d'une collection sont contenues dans une autre. Si vous ne devez
IEnumerable<T>
travailler que contre, j'utiliseraisIntersect
.La performance de cela devrait être très raisonnable, car
Intersect()
il énumérera chaque liste une seule fois. De plus, le deuxième appel àCount()
sera optimal si le type sous-jacent est unICollection<T>
plutôt qu'un simpleIEnumerable<T>
.la source
Vous pouvez également utiliser Except pour supprimer de la première liste toutes les valeurs qui existent dans la deuxième liste, puis vérifier si toutes les valeurs ont été supprimées:
Cette méthode avait l'avantage de ne pas nécessiter deux appels à Count ().
la source
C # 3.5+
Utilisation
Enumerable.All<TSource>
pour déterminer si tous les éléments List2 sont contenus dans List1:Cela fonctionnera également lorsque list1 contient encore plus que tous les éléments de list2.
la source
Contains()
appel dans unAll()
appel.bool hasAll = list2Uris.All(list1Uris.Contains);
La réponse de Kent est fine et courte, mais la solution qu'il fournit nécessite toujours une itération sur toute la première collection. Voici le code source:
Ce n'est pas toujours nécessaire. Alors, voici ma solution:
En fait, vous devriez penser à utiliser
ISet<T>
(HashSet<T>
). Il contient toutes les méthodes d'ensemble requises.IsSubsetOf
dans ton cas.la source
l'opérateur Linq SequenceEqual fonctionnerait également (mais est sensible au fait que les éléments de l'énumérable sont dans le même ordre)
la source
La solution marquée comme réponse échouerait en cas de répétitions. Si votre IEnumerable ne contient que des valeurs distinctes, il passera.
La réponse ci-dessous est pour 2 listes avec des répétitions:
la source
Vous devez utiliser HashSet au lieu de Array.
Exemple:
Référence
La seule limitation HasSet est que nous ne pouvons pas obtenir élément par index comme List ni obtenir élément par clé comme les dictionnaires. Tout ce que vous pouvez faire est de les énumérer (pour chacun, while, etc.)
S'il vous plaît laissez-moi savoir si cela fonctionne pour vous
la source
vous pouvez utiliser cette méthode pour comparer deux listes
la source