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

3
我希望您能帮我解决这个问题。我有一个List<List<double[]>>,我想要删除其中所有重复的内容。即:
1)在List<double[]>中, 有一些是重复的double[]。我想只保留List<double[]>中不重复的部分。请参见图片中的列表1和5。
2)在List<List<double[]>> 中,有一些是重复的List<double[]>。我想只保留不重复的子列表。请参见列表0和2以及列表1和3。
期望输出显示在图片中: enter image description here 我尝试了以下方法,但它并不起作用。
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();
}

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


2
你的代码有什么问题? - Hamid Pourjam
你目前得到了什么输出? - sr28
这可能会有所帮助:https://dev59.com/uIPba4cB1Zd3GeqPsncW - sr28
可能是重复问题:IEqualityComparer for SequenceEqual - Oliver
1个回答

3

除了 ToList 收集器之外,您的代码在逻辑上等同于:

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

您正在尝试在集合上使用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>,则也不需要第二个相等性比较器(您的原始代码可能已经可以正常工作)。
因此,为了避免将来出现此类问题,请尝试为您的问题声明专门的类型(而不是依赖于通用列表和数组,并像这里嵌套它们)。

1
如何在“Distinct”中使用它? - M.kazem Akhgary
1
@M.kazemAkhgary 你需要创建该类的一个实例并将其传递给Distinct函数。 - Theodoros Chatzigiannakis
你应该修复你的哈希码方法。正如你所说,它很糟糕,需要修复。 - Servy
1
@TheodorosChatzigiannakis 这样做并没有任何改善。它仍然存在所有相同的问题,最明显的是,具有相同项目但顺序不同的序列将具有相同的哈希值。 - Servy
现在它甚至不能编译。你没有声明i。如果你想让它成为索引,那么它绝对不会解决这个问题。XOR和加法的整个要点在于它们都是反射性的,因此应用它们的顺序是无关紧要的。 - Servy
显示剩余12条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接