I just discovered that Except() will remove all elements in the second list from the first, but it also has the effect that it makes all elements in the returne
Given A = [1, 2, 2, 3, 3, 3] and B = [3].
A.Except(B); returns [1, 2] as Greg Beech explained in his responseA.ExceptAll(B); from Alex Siepman response, returns [1, 2, 2, 3, 3] (and I find the name ambiguous).A.Where(v => !B.Contains(v)) from OP work around returns [1, 2, 2]I suppose that OP work around is the desired behavior, and this one as not be treated.
The main issue with OP work around is that ListO(n) and Where is also O(n) making the solution O(n²) in time (for A and B of equivalent sizes) and O(1) in memory.
We can make it O(n) in time and O(n) in memory by using hash set:
// I accept any better name for this method
public static IEnumerable ExceptFrom(
IEnumerable first,
IEnumerable second,
IEqualityComparer comparer)
{
if (first == null)
throw new ArgumentNullException(nameof(first));
if (second == null)
throw new ArgumentNullException(nameof(second));
var secondSet = second as HashSet ?? // this trick ignore the comparer
second.ToHashSet(comparer ?? EqualityComparer.Default);
// Contains is O(1) for HashSet.
return first.Where(v => !secondSet.Contains(v));
}