Basically, here's the problem statement:
Given an
IEnumerable<T> source
and anIEnumerable<T> exceptions
, return anIEnumerable<T> result
which contains all ofsource
, withoutexceptions
, only omitting exact instances of a value. I.e.: if a value appears twice insource
, but once inexceptions
, thenresult
will have that value exactly one time.
Let's take an example:
Exception list:
{ 2, 2, 3, 4, 5}
Source list:
{ 2, 2, 2, 6 }
Result:
{ 2, 6 }
Code:
public static IEnumerable<T> ExceptExact<T>(this IEnumerable<T> source, IEnumerable<T> exceptions)
{
var tExceptions = new List<T>();
tExceptions.AddRange(exceptions);
var result = new List<T>();
foreach (var el in source)
{
if (tExceptions.Contains(el))
{
tExceptions.RemoveAt(tExceptions.IndexOf(el));
}
else
{
result.Add(el);
}
}
return result;
}
Usage:
var a = new List<int> { 2, 3, 5, 4, 2 }; var b = new List<int> { 2, 2, 2, 6 }; var c = b.ExceptExact(a); var d = a.ExceptExact(b); Console.WriteLine("A: { " + string.Join(", ", a) + " }"); Console.WriteLine("B: { " + string.Join(", ", b) + " }"); Console.WriteLine("C: { " + string.Join(", ", c) + " }"); Console.WriteLine("D: { " + string.Join(", ", d) + " }");
Output:
A: { 2, 3, 5, 4, 2 } B: { 2, 2, 2, 6 } C: { 2, 6 } D: { 3, 5, 4 }
tExceptions
is a temporary list of theexceptions
parameter, because I cannot delete values from the input parameter. \$\endgroup\$