yuvs yuvs - 1 month ago 14
C# Question

Remove elements from one list that are found in another

This should be quite easy, however I am failing to see why all my methods are not working.

I have looked at all the solutions and used them appropriately however am not getting the result.

solutions include

Solution 1

Solution 2

Here is the code:

IEnumerable<feature> available = _repo.GetAvailableFeatures();
IEnumerable<feature> selected = _repo.GetSelectedFeatures();


Using Except

var filteredList = (available.Except(selected)).ToList;


Using Linq

var availableList = available.ToList();
var selectedList = selected.ToList();
availableList.RemoveAll(item => selectedList.Contains(item));


Using old fashion for

for (var i = 0; i < availableList.Count - 1; i++)
{
foreach (var t in selectedList)
{
if (availableList[i].Id == t.Id)
{
availableList.RemoveAt(i);
}
}
}


My Feature class looks like this:

public class Feature
{
public int Id;
public int Desc;
}


Can anyone see it my mistakes here?

Answer

When you use Except you need to define what "equal" means for the feature type. In your loop you define "equal" as "Ids are equal", so you could:

  • Override Equals and GetHashCode in the feature class
    • This becomes the "default" definition of equal for the type
  • Define a class that implements IEqualityComparer<feature>
    • This could be used only when that definition is needed
  • Use Where instead of Except:

    var filteredList = available.Where(a => !selected.Any(s => s.Id == a.Id))
                                .ToList();
    
    • Performance is sub-optimal but it is a simpler code solution if performance overall is not affected significantly.