Your code (excluding the ToList
collectors) seems logically equivalent to:
return input.Select(t => t.Distinct()).Distinct();
You're trying to use Distinct
on collections. That's reasonable, since you are expecting to get distinct collections.
The problem is that you have left Distinct
without logic to compare these collections. Without specifying that logic, Distinct
can't compare collections properly (by equality of each individual member).
There is another overload of Distinct
that takes an IEqualityComparer<T>
as an argument. To use it, you'll have to implement such a comparer first. A reasonable implementation (adapted from Cédric Bignon's answer) could look like this:
public class ArrayComparer<T> : IEqualityComparer<T[]>
{
public bool Equals(T[] x, T[] y)
{
return ReferenceEquals(x, y) || (x != null && y != null && x.SequenceEqual(y));
}
public int GetHashCode(T[] obj)
{
return 0;
}
}
public class ListOfArrayComparer<T> : IEqualityComparer<List<T[]>>
{
public bool Equals(List<T[]> x, List<T[]> y)
{
return ReferenceEquals(x, y) || (x != null && y != null && x.SequenceEqual(y, new ArrayComparer<T>()));
}
public int GetHashCode(List<T[]> obj)
{
return 0;
}
}
Your code should then look like this:
public static List<List<double[]>> CleanListOfListsOfDoubleArray(List<List<double[]>> input)
{
var output = new List<List<double[]>>();
for (int i = 0; i < input.Count; i++)
{
var temp = input[i].Distinct(new ArrayComparer<double>()).ToList();
output.Add(temp);
}
return output.Distinct(new ListOfArrayComparer<double>()).ToList();
}
Or even just:
public static List<List<double[]>> CleanListOfListsOfDoubleArray(List<List<double[]>> input)
{
var output = input.Select(t => t.Distinct(new ArrayComparer<double>()).ToList()).ToList();
return output.Distinct(new ListOfArrayComparer<double>()).ToList();
}
Keep in mind that this would be a lot less complicated if you used more specific types for describing your problem.
If, for example, instead of double[]
, you used a more specific pair type (like Tuple<double, double>
), you would only need to implement one comparer (the first Distinct
call could be left with its default behavior, if I remember correctly).
If, instead of the List<double>
you had a specialized PairCollection
that implements its own equality method, you wouldn't need the second equality comparer either (your original code would work as it already is, most probably).
So, to avoid problems like this in the future, try to declare specialized types for your problem (instead of relying on the generic lists and arrays and nesting them like here).