I have these two lists:
List<image> ImagesByPerimeterId
List<PerimeterTile> ImagesWithMorePerimeters
The context is the following:
I want to remove images that contain the id found in the ImagesWithMorePerimeters list from the ImagesByPerimeterId list. The ImagesWithMorePerimeters list has an imageId attribute to compare with the first one.
I have implemented this logic, and it works very well:
foreach(var i in ImagesByPerimeterId)
{
foreach(var j in ImagesWithMorePerimeters)
{
if (i.Id == j.ImageId)
{
ImagesByPerimeterId.Remove(i);
}
}
}
but I'm looking for a simpler way to compare these lists. Any suggestions?
I tried to use list.Except(), but as the lists are different objects, that did not make it
CodePudding user response:
You can do this and result will be a list of ImageId
var result = ImagesByPerimeterId.Select(i => i.ImageId).
Except(ImagesWithMorePerimeters.Select(j => j.ImageId)).ToList();
CodePudding user response:
You are trying to modify the list while iterating through it, that will cause an exception when the method Remove() is called:
InvalidOperationException: Collection was modified; enumeration operation may not execute.
If you want to do it using iteration do this:
for (var i2 = 0; i2 < ImagesWithMorePerimeters.Count; i2 )
{
for (var i1 = ImagesByPerimeterId.Count - 1; i1 >= 0; i1--)
{
if (ImagesWithMorePerimeters[i2].ImageId == ImagesByPerimeterId[i1].Id)
ImagesByPerimeterId.RemoveAt(i1);
}
}
If you want to make it shorter you can do this using Linq:
ImagesByPerimeterId.RemoveAll(image => ImagesWithMorePerimeters.Any(imageMore => image.Id == imageMore.ImageId));
Linq version will be about 5 times slower, here are the benchmark:
| Method | Mean |
|--------------- |----------:|
| UsingIteration | 2.314 us |
| UsingLinq | 10.348 us |
