Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add items to a collection if the collection does NOT already contain it by comparing a property of the items?

Basically, how do I make it so I can do something similar to: CurrentCollection.Contains(...), except by comparing if the item's property is already in the collection?

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? 
like image 885
michael Avatar asked Jun 13 '11 13:06

michael


People also ask

How do you add to a list only items that are not already in the list C#?

Use the Contains method to check if the item exists in the list. It returns true if the item exists in the list. If Contains is true, use the Add method to add the item to the list. Create a generic extension method to make it easy to add an item to the list if it doesn't exist.

What method can you use to put an item into a list T collection?

Insert(), and List. InsertRange() methods are used to add and insert items to a List<T>. List<T> is a generic class.

How do you check a list contains an item in C#?

if (myList. Contains(myString)) string element = myList. ElementAt(myList. IndexOf(myString));


2 Answers

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); } 
like image 138
R. Martinho Fernandes Avatar answered Sep 19 '22 12:09

R. Martinho Fernandes


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)); 
like image 38
Yanga Avatar answered Sep 19 '22 12:09

Yanga