J'ai le code suivant:
List<string> test1 = new List<string> { "@bob.com", "@tom.com" };
List<string> test2 = new List<string> { "[email protected]", "[email protected]" };
Je dois supprimer toute personne dans test2 qui possède @ bob.com ou @ tom.com.
Ce que j'ai essayé, c'est ceci:
bool bContained1 = test1.Contains(test2);
bool bContained2 = test2.Contains(test1);
bContained1 = false
mais bContained2 = true
. Je préférerais ne pas parcourir chaque liste en boucle, mais utiliser une requête Linq pour récupérer les données. bContained1 est la même condition pour la requête Linq que j'ai créée ci-dessous:
List<string> test3 = test1.Where(w => !test2.Contains(w)).ToList();
La requête ci-dessus fonctionne avec une correspondance exacte mais pas avec des correspondances partielles.
J'ai examiné d'autres requêtes mais je peux trouver une comparaison étroite avec Linq. Toutes les idées ou n'importe où vous pouvez m'indiquer seraient d'une grande aide.
var test2NotInTest1 = test2.Where(t2 => test1.Count(t1 => t2.Contains(t1))==0);
Version plus rapide selon la suggestion de Tim:
var test2NotInTest1 = test2.Where(t2 => !test1.Any(t1 => t2.Contains(t1)));
var output = emails.Where(e => domains.All(d => !e.EndsWith(d)));
Ou si vous préférez:
var output = emails.Where(e => !domains.Any(d => e.EndsWith(d)));
bool doesL1ContainsL2 = l1.Intersect(l2).Count() == l2.Count;
L1 et L2 sont tous deux List<T>
Pas besoin d'utiliser Linq comme ceci ici, car il existe déjà une méthode d'extension pour le faire pour vous.
Enumerable.Except<TSource>
http://msdn.Microsoft.com/en-us/library/bb336390.aspx
Vous avez juste besoin de créer votre propre comparateur pour comparer au besoin.
quelque chose comme ça:
List<string> test1 = new List<string> { "@bob.com", "@tom.com" };
List<string> test2 = new List<string> { "[email protected]", "[email protected]" };
var res = test2.Where(f => test1.Count(z => f.Contains(z)) == 0)
Exemple en direct: ici
Essayez ce qui suit:
List<string> test1 = new List<string> { "@bob.com", "@tom.com" };
List<string> test2 = new List<string> { "[email protected]", "[email protected]" };
var output = from goodEmails in test2
where !(from email in test2
from domain in test1
where email.EndsWith(domain)
select email).Contains(goodEmails)
select goodEmails;
Cela fonctionne avec l'ensemble de test fourni (et semble correct).
List<string> test1 = new List<string> { "@bob.com", "@tom.com" };
List<string> test2 = new List<string> { "[email protected]", "[email protected]", "[email protected]" };
var result = (from t2 in test2
where test1.Any(t => t2.Contains(t)) == false
select t2);
Si vous voulez utiliser le formulaire de requête, il est lisible et plus ou moins "performant", comme cela pourrait être.
Ce que je veux dire, c'est que ce que vous essayez de faire est un algorithme O (N * M), c’est-à-dire que vous devez traverser N éléments et les comparer à M valeurs. Ce que vous voulez, c'est parcourir la première liste une seule fois et la comparer à l'autre liste autant de fois que nécessaire (dans le pire des cas, le courrier électronique est valide puisqu'il doit être comparé à tous les domaines de la liste noire).
from t2 in test
On boucle la liste de courriel une fois.
test1.Any(t => t2.Contains(t)) == false
nous comparons avec la liste noire et lorsque nous avons trouvé un résultat correspondant (donc ne comparant pas avec la liste complète si ce n'est pas nécessaire)
select t2
Gardez ceux qui sont propres.
Donc, voici ce que je voudrais utiliser.