Remove everything duplicated in List <List <double [] >>

I hope you can help me with this. I have a List <List <double [] → and I want to remove all duplicates in such a list. I.e:

1) There are some of the double [] in List <double []> that are duplicates. I want to keep only duplicates not duplicates [] in a list <double []>. See Lists 1 and 5 in the figure.

2) Inside List <List <double [] → there are some of List <double []> which are duplicated. I want to keep only non-duplicate lists. See Lists 0 and 2 and Lists 1 and 3.

The desired result is indicated in the figure:

enter image description here

I tried the following but it doesn't work.

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().ToList();
        output.Add(temp);
    }
    return output.Distinct().ToList();
}

      

Could you help me with this?

+3


source to share


1 answer


Your code (excluding the collectors ToList

) seems to be logically equivalent:

return input.Select(t => t.Distinct()).Distinct();

      

You are trying to use Distinct

for collections. This is reasonable as you would expect different collections.

The problem is that you left it Distinct

without logic to compare these collections. Without specifying this logic, Distinct

it cannot correctly match collections (by making each individual member equal).

There is another overload Distinct

that takes IEqualityComparer<T>

as an argument. To use it, you will have to implement such a comparator first. A sane implementation (adapted from Cédric Bignon's answer ) might 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 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 much less difficult if you used more specific types to describe your problem.

If, for example, double[]

you used a more specific type of pair (for example Tuple<double, double>

) instead , you would only need to implement one comparator (the first call Distinct

could have been left with the default behavior, if I remember correctly).

If instead List<double>

you had a specialized PairCollection

one that implements its own equality method, you don't need a second equality matcher (your original code will work as it already is, most likely).

So, to avoid similar problems in the future, try declaring specialized types for your problem (instead of relying on generic lists and arrays and inserting them like here).

+3


source







All Articles