having a List of int arrays like:
List intArrList = new List();
intArrList.Add(new int[3] { 0, 0, 0 });
intArrList.Add(new int[5] {
Input list;
List<List<int>> initList = new List<List<int>>();
initList.Add(new List<int>{ 0, 0, 0 });
initList.Add(new List<int>{ 20, 30, 10, 4, 6 }); //this
initList.Add(new List<int> { 1, 2, 5 });
initList.Add(new List<int> { 20, 30, 10, 4, 6 }); //this
initList.Add(new List<int> { 12, 22, 54 });
initList.Add(new List<int> { 1, 2, 6, 7, 8 });
initList.Add(new List<int> { 0, 0, 0, 0 });
You can create a result list, and before adding elements you can check if it is already added. I simply compared the list counts and used p.Except(item).Any()
call to check if the list contains that element or not.
List<List<int>> returnList = new List<List<int>>();
foreach (var item in initList)
{
if (returnList.Where(p => !p.Except(item).Any() && !item.Except(p).Any()
&& p.Count() == item.Count() ).Count() == 0)
returnList.Add(item);
}
Perf comparison of @S.Akbari's and @Mick's solutions using BenchmarkDotNet
EDIT:
SAkbari_FindDistinctWithoutLinq has redundant call to ContainsKey, so i added impoved and faster version: SAkbari_FindDistinctWithoutLinq2
Method | Mean | Error | StdDev | --------------------------------- |---------:|----------:|----------:| SAkbari_FindDistinctWithoutLinq | 4.021 us | 0.0723 us | 0.0676 us | SAkbari_FindDistinctWithoutLinq2 | 3.930 us | 0.0529 us | 0.0495 us | SAkbari_FindDistinctLinq | 5.597 us | 0.0264 us | 0.0234 us | Mick_UsingGetHashCode | 6.339 us | 0.0265 us | 0.0248 us |
BenchmarkDotNet=v0.10.13, OS=Windows 10 Redstone 3 [1709, Fall Creators Update] (10.0.16299.248) Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical cores and 4 physical cores Frequency=3515625 Hz, Resolution=284.4444 ns, Timer=TSC .NET Core SDK=2.1.100 [Host] : .NET Core 2.0.5 (CoreCLR 4.6.26020.03, CoreFX 4.6.26018.01), 64bit RyuJIT DefaultJob : .NET Core 2.0.5 (CoreCLR 4.6.26020.03, CoreFX 4.6.26018.01), 64bit RyuJIT
Benchmark:
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
public class Program
{
List<int[]> intArrList = new List<int[]>
{
new int[] { 0, 0, 0 },
new int[] { 20, 30, 10, 4, 6 }, //this
new int[] { 1, 2, 5 },
new int[] { 20, 30, 10, 4, 6 }, //this
new int[] { 12, 22, 54 },
new int[] { 1, 2, 6, 7, 8 },
new int[] { 0, 0, 0, 0 }
};
[Benchmark]
public List<int[]> SAkbari_FindDistinctWithoutLinq() => FindDistinctWithoutLinq(intArrList);
[Benchmark]
public List<int[]> SAkbari_FindDistinctWithoutLinq2() => FindDistinctWithoutLinq2(intArrList);
[Benchmark]
public List<int[]> SAkbari_FindDistinctLinq() => FindDistinctLinq(intArrList);
[Benchmark]
public List<int[]> Mick_UsingGetHashCode() => FindDistinctLinq(intArrList);
static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<Program>();
}
public static List<int[]> FindDistinctWithoutLinq(List<int[]> lst)
{
var dic = new Dictionary<string, int[]>();
foreach (var item in lst)
{
string key = string.Join(",", item.OrderBy(c => c));
if (!dic.ContainsKey(key))
{
dic.Add(key, item);
}
}
return dic.Values.ToList();
}
public static List<int[]> FindDistinctWithoutLinq2(List<int[]> lst)
{
var dic = new Dictionary<string, int[]>();
foreach (var item in lst)
dic.TryAdd(string.Join(",", item.OrderBy(c => c)), item);
return dic.Values.ToList();
}
public static List<int[]> FindDistinctLinq(List<int[]> lst)
{
return lst.GroupBy(p => string.Join(", ", p.OrderBy(c => c)))
.Select(c => c.First().ToArray()).ToList();
}
public static List<int[]> UsingGetHashCode(List<int[]> lst)
{
return lst.Select(a => a.OrderBy(e => e).ToArray()).Distinct(new IntArrayEqualityComparer()).ToList();
}
}
public class IntArrayEqualityComparer : IEqualityComparer<int[]>
{
public bool Equals(int[] x, int[] y)
{
return ArraysEqual(x, y);
}
public int GetHashCode(int[] obj)
{
int hc = obj.Length;
for (int i = 0; i < obj.Length; ++i)
{
hc = unchecked(hc * 17 + obj[i]);
}
return hc;
}
static bool ArraysEqual<T>(T[] a1, T[] a2)
{
if (ReferenceEquals(a1, a2))
return true;
if (a1 == null || a2 == null)
return false;
if (a1.Length != a2.Length)
return false;
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (int i = 0; i < a1.Length; i++)
{
if (!comparer.Equals(a1[i], a2[i])) return false;
}
return true;
}
}
}