Подтвердить что ты не робот

Запрос LINQ, чтобы найти элементы в списке, содержащиеся в другом списке

У меня есть следующий код:

List<string> test1 = new List<string> { "@bob.com", "@tom.com" };
List<string> test2 = new List<string> { "[email protected]", "[email protected]" };

Мне нужно удалить кого-нибудь из test2, у которого есть @bob.com или @tom.com.

Я пробовал это:

bool bContained1 = test1.Contains(test2);
bool bContained2 = test2.Contains(test1);

bContained1 = false, но bContained2 = true. Я бы предпочел не перебирать каждый список, а вместо этого использовать запрос Linq для извлечения данных. bContained1 - это то же условие для запроса Linq, который я создал ниже:

List<string> test3 = test1.Where(w => !test2.Contains(w)).ToList();

Запрос выше работает с точным совпадением, но не с частичными совпадениями.

Я просмотрел другие запросы, но я могу найти близкое сравнение с этим с Linq. Любые идеи или все, что вы можете мне указать, было бы большой помощью.

4b9b3361

Ответ 1

var test2NotInTest1 = test2.Where(t2 => test1.Count(t1 => t2.Contains(t1))==0);

Более быстрая версия в соответствии с предложением Тима:

var test2NotInTest1 = test2.Where(t2 => !test1.Any(t1 => t2.Contains(t1)));

Ответ 2

var output = emails.Where(e => domains.All(d => !e.EndsWith(d)));

Или, если вы предпочитаете:

var output = emails.Where(e => !domains.Any(d => e.EndsWith(d)));

Ответ 3

bool doesL1ContainsL2 = l1.Intersect(l2).Count() == l2.Count;

L1 и L2 оба List<T>

Ответ 4

Не нужно использовать Linq, как здесь, потому что уже существует метод расширения для этого.

Enumerable.Except<TSource>

http://msdn.microsoft.com/en-us/library/bb336390.aspx

Вам просто нужно создать свой собственный сравнитель для сравнения по мере необходимости.

Ответ 5

что-то вроде этого:

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)

Пример в реальном времени: здесь

Ответ 6

Попробуйте следующее:

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;

Это работает с установленным набором тестов (и выглядит правильно).

Ответ 7

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);

Если форма запроса - это то, что вы хотите использовать, это разборчиво и более или менее "исполнитель", как это могло бы быть.

Что я имею в виду, так это то, что вы пытаетесь сделать, это алгоритм O (N * M), то есть вам нужно пересечь N элементов и сравнить их с значениями M. Вы хотите, чтобы пройти первый список только один раз и сравнить с другим списком столько раз, сколько необходимо (в худшем случае, когда письмо действительно, поскольку оно должно сравниваться с каждым черным доменом).

from t2 in test мы запустим список адресов электронной почты один раз.

test1.Any(t => t2.Contains(t)) == false мы сравниваем с черным списком и когда мы нашли одно совпадение return (следовательно, не сравнивая его со всем списком, если не нужно)

select t2 сохранить те, которые чисты.

Так вот что я буду использовать.

Ответ 8

var List2 = OriginalList.Where(item => List1.Any(item2 => item2.ID == item.ID));

Ответ 9

List<string> l = new List<string> { "@bob.com", "@tom.com" };
List<string> l2 = new List<string> { "[email protected]", "[email protected]" };
List<string> myboblist= (l2.Where (i=>i.Contains("bob")).ToList<string>());
foreach (var bob in myboblist)
    Console.WriteLine(bob.ToString());

Ответ 10

Я думаю, что это было бы проще всего:

test1.ForEach(str => test2.RemoveAll(x=>x.Contains(str)));