删除列表中重复的所有内容<List<double[]>>

Remove everything which is duplicate in a List<List<double[]>>

我希望你能帮我解决这个问题。我有一个 List < List < double[] > > 并且我想删除该列表中重复的所有内容。即:

1) 在 List < double[] > 中有一些 double[] duplicate.I只想在 List < double[] > 中保留非重复的 double[]。见图中清单1和清单5。

2) 在 List < List < double[] > > 中有一些 List < double[] > 是复制。我只想保留非重复列表。请参阅列表 0 和 2 以及列表 1 和 3。

图片中指定了想要的输出:

我尝试了以下方法,但它不起作用。

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();
}

你能帮我解决这个问题吗?

您的代码(不包括 ToList 收集器)在逻辑上似乎等同于:

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

您正在尝试对集合使用 Distinct。这是合理的,因为您期望获得不同的 collections.

问题是您 Distinct 没有逻辑来比较这些集合。如果不指定该逻辑,Distinct 无法正确比较集合(通过每个成员的相等性)。

Distinct 的另一个重载以 IEqualityComparer<T> 作为参数。要使用它,您必须先实现这样一个比较器。合理的实现(改编自 Cédric Bignon's answer)可能如下所示:

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;
    }
}

您的代码应该如下所示:

    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();
    }

甚至只是:

    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();
    }

请记住,如果您使用更具体的类型来描述您的问题,这会简单得多。

例如,如果您使用更具体的对类型(如 Tuple<double, double>)而不是 double[],则您只需要实现一个比较器(第一个 Distinct如果我没记错的话,调用可以保留其默认行为)。

如果您有一个专用的 PairCollection 而不是 List<double> 来实现自己的相等方法,则您也不需要第二个相等比较器(您的原始代码已经可以正常工作了是,很有可能)。

因此,为避免将来出现此类问题,请尝试为您的问题声明专用类型(而不是像此处那样依赖通用列表和数组并嵌套它们)。