Ответ 1
var test2NotInTest1 = test2.Where(t2 => test1.Count(t1 => t2.Contains(t1))==0);
Более быстрая версия в соответствии с предложением Тима:
var test2NotInTest1 = test2.Where(t2 => !test1.Any(t1 => t2.Contains(t1)));
У меня есть следующий код:
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. Любые идеи или все, что вы можете мне указать, было бы большой помощью.
var test2NotInTest1 = test2.Where(t2 => test1.Count(t1 => t2.Contains(t1))==0);
Более быстрая версия в соответствии с предложением Тима:
var test2NotInTest1 = test2.Where(t2 => !test1.Any(t1 => t2.Contains(t1)));
var output = emails.Where(e => domains.All(d => !e.EndsWith(d)));
Или, если вы предпочитаете:
var output = emails.Where(e => !domains.Any(d => e.EndsWith(d)));
bool doesL1ContainsL2 = l1.Intersect(l2).Count() == l2.Count;
L1 и L2 оба List<T>
Не нужно использовать Linq, как здесь, потому что уже существует метод расширения для этого.
Enumerable.Except<TSource>
http://msdn.microsoft.com/en-us/library/bb336390.aspx
Вам просто нужно создать свой собственный сравнитель для сравнения по мере необходимости.
что-то вроде этого:
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)
Пример в реальном времени: здесь
Попробуйте следующее:
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;
Это работает с установленным набором тестов (и выглядит правильно).
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
сохранить те, которые чисты.
Так вот что я буду использовать.
var List2 = OriginalList.Where(item => List1.Any(item2 => item2.ID == item.ID));
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());
Я думаю, что это было бы проще всего:
test1.ForEach(str => test2.RemoveAll(x=>x.Contains(str)));