Add items to a collection if the collection does NOT already contain it by comparing a property of the items?
Solution 1:
You start by finding which elements are not already in the collection:
var newItems = DownloadedItems.Where(x => !CurrentCollection.Any(y => x.bar == y.bar));
And then just add them:
foreach(var item in newItems)
{
CurrentCollection.Add(item);
}
Note that the first operation may have quadratic complexity if the size of DownloadedItems
is close to the size of CurrentCollection
. If that ends up causing problems (measure first!), you can use a HashSet
to bring the complexity down to linear:
// 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);
}
Solution 2:
You can use Enumerable.Except:
It will compare the two lists and return elements that appear only in the first list.
CurrentCollection.AddRange(DownloadedItems.Except(CurrentCollection));
Solution 3:
Using R.Martinho Fernandes method and converting to 1 line:
CurrentCollection.AddRange(DownloadedItems.Where(x => !CurrentCollection.Any(y => y.bar== x.bar)));
Solution 4:
You can call the Any
method and pass a value to compare to whatever property of the type of object in the collection
if (!CurrentCollection.Any(f => f.bar == someValue))
{
// add item
}
a more complete solution could be:
DownloadedItems.Where(d => !CurrentCollection.Any(c => c.bar == d.bar)).ToList()
.ForEach(f => CurrentCollection.Add(f));