C# more efficient way of comparing two collections

You can do it like this:

// 1) List of cars in newCars and not in currentCars
var newButNotCurrentCars = newCars.Except(currentCars);

// 2) List of cars in currentCars and not in newCars
var currentButNotNewCars = currentCars.Except(newCars);

The code uses the Enumerable.Except extension method (available in .Net 3.5 and over).

I believe this fulfills your criteria of "less code, less mechanics, and more readable".


You can use Except:

var currentCarsNotInNewCars = currentCars.Except(newCars);
var newCarsNotInCurrentCars = newCars.Except(currentCars);

But this has no performance benefit over the foreach solution. It just looks cleaner.
Also, be aware of the fact, that you need to implement IEquatable<T> for your Car class, so the comparison is done on the ID and not on the reference.

Performancewise, a better approach would be to not use a List<T> but a Dictionary<TKey, TValue> with the ID as the key:

var currentCarsDictionary = currentCars.ToDictionary(x => x.ID);
var newCarsDictionary = newCars.ToDictionary(x => x.ID);

var currentCarsNotInNewCars = 
    currentCarsDictionary.Where(x => !newCarsDictionary.ContainsKey(x.Key))
                         .Select(x => x.Value);

var newCarsNotInCurrentCars = 
    newCarsDictionary.Where(x => !currentCarsDictionary.ContainsKey(x.Key))
                     .Select(x => x.Value);

If you start with them in HashSets you can use the Except method.

HashSet<Car> currentCars = GetCurrentCars();
HashSet<Car> newCars = GetNewCars();

currentCars.Except(newCars);
newCars.Except(currentCars);

It would be much faster w/ a set than a list. (Under the hood a list is just doing a foreach, sets can be optimized).

Tags:

C#

.Net

C# 4.0