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

Добавить элементы в коллекцию, если коллекция НЕ содержит ее, сравнивая свойство элементов?

В принципе, как это сделать, я могу сделать что-то похожее на: CurrentCollection.Contains(...), за исключением сравнения, если свойство элемента уже находится в коллекции?

public class Foo
{
    public Int32 bar;
}


ICollection<Foo> CurrentCollection;
ICollection<Foo> DownloadedItems;

//LINQ: Add any downloaded items where the bar Foo.bar is not already in the collection?
4b9b3361

Ответ 1

Вы начинаете с нахождения тех элементов, которые еще не собраны в коллекции:

var newItems = DownloadedItems.Where(x => !CurrentCollection.Any(y => x.bar == y.bar));

А затем просто добавьте их:

foreach(var item in newItems)
{
    CurrentCollection.Add(item);
}

Обратите внимание, что первая операция может иметь квадратичную сложность, если размер DownloadedItems близок к размеру CurrentCollection. Если это закончится тем, что вызывает проблемы (сначала измерьте!), Вы можете использовать HashSet, чтобы снизить сложность до линейного:

// collect all existing values of the property bar
var existingValues = new HashSet<Foo>(from x in CurrentCollection select x.bar);
// pick items that have a property bar that doesn't exist yet
var newItems = DownloadedItems.Where(x => !existingValues.Contains(x.bar));
// Add them
foreach(var item in newItems)
{
    CurrentCollection.Add(item);
}

Ответ 2

Использование метода Р.Мартинью Фернандеса и преобразование в 1 строку:

CurrentCollection.AddRange(DownloadedItems.Where(x => !CurrentCollection.Any(y => y.bar== x.bar)));

Ответ 3

Вы можете вызвать метод Any и передать значение для сравнения с любым свойством типа объекта в коллекции

if (!CurrentCollection.Any(f => f.bar == someValue))
{
    // add item
}

более полное решение может быть:

DownloadedItems.Where(d => !CurrentCollection.Any(c => c.bar == d.bar)).ToList()
    .ForEach(f => CurrentCollection.Add(f));

Ответ 4

Или используя All

CurrentCollection
    .AddRange(DownloadedItems.Where(x => CurrentCollection.All(y => y.bar != x.bar)));

Ответ 5

var newItems = DownloadedItems.Where(i => !CurrentCollection.Any(c => c.Attr == i.Attr));

Ответ 6

Вы можете сделать это следующим образом:

CurrentCollection.Any(x => x.bar == yourGivenValue)