using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
public static class Program
public static int loopcnt = 0;
public static IEnumerable<T> ExceptFrom<T>(
this IEnumerable<T> first,
throw new ArgumentNullException();
throw new ArgumentNullException();
var secondSet = second as HashSet<T> ??
second.ToHashSet(EqualityComparer<T>.Default);
return first.Where(v => !secondSet.Equals(v));
public static IEnumerable<T> ExceptIndistinct<T>(this IEnumerable<T> first, IEnumerable<T> second)
if(first == null) { throw new ArgumentNullException("first"); }
if(second == null) { throw new ArgumentNullException("second"); }
var secondCounts = new Dictionary<T, int>(EqualityComparer<T>.Default);
foreach(var item in second)
if(item == null) { nullCount++; }
else if(secondCounts.TryGetValue(item, out count)) { secondCounts[item] = count + 1; }
else { secondCounts.Add(item, 1); }
foreach(var item in first)
if(nullCount < 0) { yield return item; }
else if(secondCounts.TryGetValue(item, out count))
secondCounts.Remove(item);
else { secondCounts[item] = count - 1; }
else { yield return item; }
public static void Main()
Stopwatch sw = new Stopwatch();
string[] arrA = new string[] { "a", "7", "1", "2", "3", "4", "5", "9", "7", "7", "1","222222222222222222","22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222323" };
string[] arrB = new string[] { "a", "1", "1", "2", "2", "3", "4", "5", "5", "5", "5","999999999999999999","22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222323" };
Console.WriteLine("RANDOM CASE -two unorderd, not unique lists ");
Console.WriteLine("A = " + string.Join(",", arrA));
Console.WriteLine("B = " + string.Join(",", arrB));
Console.WriteLine("A count = " + arrA.Count());
Console.WriteLine("B count = " + arrB.Count());
string[] arrBminusA = new string[arrB.Length];
string[] arrAminuB = new string[arrA.Length];
BitArray bitArrAminusB = new BitArray(arrA.Length);
BitArray bitarrBminusA = new BitArray(arrB.Length);
for (int b = 0; b < arrB.Length; b++)
for (a = 0; a < arrA.Length; a++)
if (!bitArrAminusB[a] && arrA[a].Length == arrB[b].Length && arrA[a] == arrB[b])
bitArrAminusB.Set(a, true);
bitarrBminusA.Set(b, true);
for (int aa = 0; aa < arrA.Length; aa++)
arrAminuB[idxa++] = arrA[aa];
for (int bb = 0; bb < arrB.Length; bb++)
arrBminusA[idxb++] = arrB[bb];
Console.WriteLine("(A-B) Result = " + string.Join(",", arrAminuB).Trim(','));
Console.WriteLine("(B-A) Result = " + string.Join(",", arrBminusA).TrimEnd(','));
Console.WriteLine("No. of loops = " + loopcnt);
Console.WriteLine("No. of loops = " + arrA.Length*2 + " - Post copy using BitArray to a sized array");
Console.WriteLine("Result Unorderd Final A then B = " + (string.Join(",", arrAminuB)).Trim(',') + "," + string.Join(",", arrBminusA).Trim(',') + " in " + sw.ElapsedTicks + " ticks.");
Console.WriteLine("Result Unorderd Final B then A = " + (string.Join(",", arrBminusA)).Trim(',') + "," + string.Join(",",arrAminuB).Trim(',') + " in " + sw.ElapsedTicks + " ticks.");
Console.WriteLine("Note: In a VS solution this is 47 ticks.");
List<string> D = arrBminusA.ToList().Concat(arrAminuB.ToList()).ToList();
Console.WriteLine("Result Ordered Final = " + string.Join(",", D).TrimStart(','));
Console.WriteLine("Result O(n^2+2n) but very fast - can you beat it?");
Console.WriteLine("\n\nExceptIndistinct - Reddit Solution by UninformedPleb\n");
List<string> listA = new List<string> { "a", "7", "1", "2", "3", "4", "5", "9", "7", "7", "1","222222222222222222","22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222323" };
List<string> listB = new List<string> { "1", "1", "2", "2", "3", "4", "5", "5", "5", "5" };
List<string> listC = listA.ExceptIndistinct(listB).ToList();
List<string> listD = listB.ExceptIndistinct(listA).ToList();
Console.WriteLine("No. of loops = " + loopcnt);
Console.WriteLine("Result Unorderd Final A then B = " + (string.Join(",", listC)).Trim(',') + "," + string.Join(",", listD).Trim(',') + " \nin " + sw.ElapsedTicks + " ticks.");
Console.WriteLine("\n\nExceptIndistinct - Reddit Solution by UninformedPleb using arrays\n");
string[] arrAA = new string[] { "a", "7", "1", "2", "3", "4", "5", "9", "7", "7", "1","222222222222222222","22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222323" };
string[] arrBB = new string[] { "1", "1", "2", "2", "3", "4", "5", "5", "5", "5","999999999999999999","22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222" };
string[] listCC = arrAA.ExceptIndistinct(arrBB).ToArray();
string[] listDD = arrBB.ExceptIndistinct(arrAA).ToArray();
Console.WriteLine("No. of loops = " + loopcnt);
Console.WriteLine("Result Unorderd Final A then B = " + (string.Join(",", listC)).Trim(',') + "," + string.Join(",", listD).Trim(',') + " \nin " + sw.ElapsedTicks + " ticks.");
Console.WriteLine("\n\nStackOverflow ExceptFrom\n");
string[] arrAAA = new string[] { "a", "7", "1", "2", "3", "4", "5", "9", "7", "7", "1","222222222222222222","22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222323" };
string[] arrBBB = new string[] { "1", "1", "2", "2", "3", "4", "5", "5", "5", "5","999999999999999999","22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222" };
string[] listCCC = arrAAA.ExceptFrom(arrBBB).ToArray();
string[] listDDD = arrBBB.ExceptFrom(arrAAA).ToArray();
Console.WriteLine("No. of loops = " + loopcnt);
Console.WriteLine("Result Unorderd Final A then B = " + (string.Join(",", listC)).Trim(',') + "," + string.Join(",", listD).Trim(',') + " \nin " + sw.ElapsedTicks + " ticks.");