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 HashSet
s 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).