Использование предложения .Where и условных для массива фильтров - PullRequest
0 голосов
/ 03 мая 2018

У меня есть 2 IEnumerable списки, у которых есть метод с именем GetId(), который возвращает integer.

IEnumerable oldBoats
IEnumerable updatedBoats

Я хочу сравнить оба списка. Если updatedBoats.getId() возвращает уникальный идентификатор по сравнению с oldBoats, я хочу добавить его в список.

Итак, я сделал это:

IEnumerable<Boat> newBoats = updatedBoats
    .Where(c => oldBoats
    .Any(d => d.GetId() != c.GetId())
    .ToList()

Текущие идентификаторы для oldBoats и newBoats: [1, 2, 3, 4, 5]. Я хочу проверить базовый вариант, и это не проходит. newBoats всегда возвращает список всех идентификаторов, когда он должен возвращать none. Я неправильно делаю заказы c и d?

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Что делает этот код

IEnumerable<Boat> newBoats = updatedBoats.Where(c=> oldBoats.Any(d =>d.GetId() != c.GetId()).ToList()

примерно означает: «дайте мне все обновленные лодки, чей идентификатор не соответствует хотя бы одному из старых идентификаторов лодок». Это не то, что вы хотите. Логика, которую вы хотите, это «дать мне все обновленные лодки, чей ID не совпадает ни с одним из старых идентификаторов лодок», и это правильно указано @zeroef:

var newBoats = updatedBoats.Where(u => !oldBoats.Any(o => o.GetId() == u.GetId()));  
// This is O(o * n) for # of old boats * # of updates that are new boats, and something like O((o/2)*n) for # of old boats * number of updated old boats

Тем не менее, обратите внимание на мой комментарий. Это было бы более эффективно реализовано с использованием HashSet<T>:

// This is O(n) for # of updated boats
var newBoatIds = new HashSet<Int32>(updatedBoats.Select(b => b.GetId())); 
// This is O(n) for # of old boats
newBoatIds.ExceptWith(oldBoats.Select(b => b.GetId()));

Это значительно уменьшает количество вложенных итераций, и вы увидите разницу, если у вас много лодок (и особенно если у вас много новых лодок в вашем обновлении).

Подход HashSet работает для идентификаторов, но вы можете также заставить его работать для самих сущностей, если вы реализуете Equals () и GetHashcode () в классе Boat, используя идентификатор для сравнения.

0 голосов
/ 03 мая 2018

Как насчет этого?

var newBoats = updatedBoats.Where(u => !oldBoats.Any(o => o.GetId() == u.GetId()));
...