If you want to see the duplicates also, you can use this variant of Except:
public static IEnumerable<TSource> ExceptWithDuplicates<TSource>(
this IEnumerable<TSource> first,
IEnumerable<TSource> second)
{
if (first == null) { throw new ArgumentNullException("first"); }
if (second == null) { throw new ArgumentNullException("second"); }
var secondList = second.ToList();
return first.Where(s => !secondList.Remove(s));
}
public static IEnumerable<TSource> ExceptWithDuplicates<TSource>(
this IEnumerable<TSource> first,
IEnumerable<TSource> second,
IEqualityComparer<TSource> comparer)
{
if (first == null) { throw new ArgumentNullException("first"); }
if (second == null) { throw new ArgumentNullException("second"); }
var comparerUsed = comparer ?? EqualityComparer<TSource>.Default;
var secondList = second.ToList();
foreach (var item in first)
{
if (secondList.Contains(item, comparerUsed))
{
secondList.Remove(item);
}
else
{
yield return item;
}
}
}
Now you can do this:
var first = new [] { 1, 1, 1, 2, 2, 2, 3, 3 };
var second = new[] { 1, 2, 2, 4 };
var withoutDuplicates = first.Except(second); // 3
var witDuplicates = first.ExceptWithDuplicates(second); // 1, 1, 2, 3, 3 : Note that 1 and 2 are also in the list