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 |