#c_sharp
Есть два условных класса: public class One{ public string Common {get;set;} ...} public class Two{ public string Common {get;set;} ...} В данном примере показана одна переменная в каждом классе, она будет содержать одинаковые значения. Кроме этой переменной в каждом классе будет по 5 других, которые имеют разные, никак несвязанные значения. Есть списки: ListListOne = new List (); List ListTwo = new List (): Необходимо сравнить эти 2 списка, и убрать из них те элементы, у которых переменная Common совпадает (т.е. есть элементы в разных списках, у которых одинакова эта переменная). На ум приходит только foreach, завернутый в другой foreach, но это перебор достаточного большого числа вариантов (в каждом списке будет около 50-ти элементов), есть ли более оптимизированный подход?
Ответы
Ответ 1
Можно вот так, но все равно "за кулисами" выполняются циклы: ListListOne = new List (); List ListTwo = new List (); var result=ListOne.Join(ListTwo,ok=>ok.Common,ik=>ik.Common,(one,two)=>new {one,two}).ToList(); ListOne.RemoveAll(x=>result.Any(r => x==r.one)); ListTwo.RemoveAll(x=>result.Any(r => x==r.two)); P.S Есть еще вариант написать кастомный EqualityComparer для object'ов. Внутри приводить к нужному типу и выполнять сравнение. Затем идти циклом и добавлять в этот HashSet значения поочередно. Если оно не было добавлено, значит пересечении => удаляем элемент из исходных коллекций. Правда, не знаю, на сколько это будет быстрее. В теории должно. Ответ 2
Еще вариант: var commons = ListOne.Select(o => o.Common).Intersect(ListTwo.Select(t => t.Common)).ToList(); // Тут, скорее всего, лучше будет вместо `ToList()` использовать // `.ToHashSet()` если используется .NET 4.7.2+ или .NET Core 2.0+, // либо `ToDictionary(x => x)` для более старых версий ListOne.RemoveAll(o => commons.Contains(o.Common)); ListTwo.RemoveAll(t => commons.Contains(t.Common)); Внутри Intersect используется хэш-таблица, поэтому должно работать быстрее. Ну и не создаем лишних экземпляров анонимного класса.Ответ 3
Вариант с hashset-ом дублируемых "ключей" var dublicateKeys = new HashSet(ListOne.Where(x => ListTwo.Exists(y => y.Common == x.Common)).Select(x => x.Common)); ListOne.RemoveAll(x => dublicateKeys.Contains(x.Common)); ListTwo.RemoveAll(x => dublicateKeys.Contains(x.Common));
Комментариев нет:
Отправить комментарий