在C#中删除一个列表中的重复列表[英] Remove duplicate lists inside a list of lists in C#

本文是小编为大家收集整理的关于在C#中删除一个列表中的重复列表的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

如何从主列表中删除重复的内部列表?

var list1 = new List<object>() { 1,2,3 };
var list2 = new List<object>() { 4,5,6 };
var list3 = new List<object>() { 1,2,3 };

List<List<object>> mainList = new List<List<object>>() {list1, list2, list3};

我想从 mainList 中删除 list3 以便在 mainList 中没有重复.

推荐答案

更新: 如评论中所述,项目顺序无关紧要,因此 {3,2,1} 和 {1,2,3} 被视为重复.

<小时>

您的问题存在一些疑虑.您的内部列表包含对象.如果这意味着 object 可以是任何东西而不仅仅是 int 那么你应该确保这些对象也覆盖 Equals 和 GetHashCode (或实现 IEquatable<TSelf> 其中 TSelf 是实现类型).

如果您的内部列表只包含原始类型或常见的只读结构,例如 DateTime 或 TimeSpan,那么您不必担心.

您可以使用 Distinct 和 EqualityComparer 接口

var list1 = new List<object>() { 1, 2, 3 };
var list2 = new List<object>() { 4, 5, 6 };
var list3 = new List<object>() { 1, 2, 3 };

List<List<object>> mainList = new List<List<object>>() { list1, list2, list3 };

mainList = mainList.Distinct(ListEqualityComparer<object>.Default).ToList();

平等比较器实现.

public class ListEqualityComparer<T> : IEqualityComparer<List<T>>
{
    private readonly IEqualityComparer<T> _itemEqualityComparer;

    public ListEqualityComparer() : this(null) { }

    public ListEqualityComparer(IEqualityComparer<T> itemEqualityComparer)
    {
        _itemEqualityComparer = itemEqualityComparer ?? EqualityComparer<T>.Default;
    }

    public static readonly ListEqualityComparer<T> Default = new ListEqualityComparer<T>();

    public bool Equals(List<T> x, List<T> y)
    {
        if (ReferenceEquals(x, y)) return true;
        if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) return false;
        return x.Count == y.Count && !x.Except(y, _itemEqualityComparer).Any();
    }

    public int GetHashCode(List<T> list)
    {
        int hash = 17;
        foreach (var itemHash in list.Select(x => _itemEqualityComparer.GetHashCode(x))
                                     .OrderBy(h => h))
        {
            hash += 31 * itemHash;
        }
        return hash;
    }
}

如果您的对象没有覆盖 Equals 和 GetHashCode,您也可以为您的项目创建另一个相等比较器并将其传递给此相等比较器.

mainList = mainList.Distinct(new ListEqualityComparer<object>(myItemEqualityComparer)).ToList();

其中 myItemEqualityComparer 用于比较您的 objects

本文地址:https://www.itbaoku.cn/post/1556768.html

问题描述

How do I remove duplicate inner lists from main list?

var list1 = new List<object>() { 1,2,3 };
var list2 = new List<object>() { 4,5,6 };
var list3 = new List<object>() { 1,2,3 };

List<List<object>> mainList = new List<List<object>>() {list1, list2, list3};

I want to remove the list3 from the mainList so that no duplicates in the mainList.

推荐答案

Update: as mentioned in comments, order of items does not matter so {3,2,1} and {1,2,3} are considered duplicate.


There are a few concerns about your question. your inner list contains objects. if that means object can be anything and not just an int then you should make sure those objects override Equals and GetHashCode as well (or implement IEquatable<TSelf> where TSelf is the implementing type).

If your inner list just contains primitive types or common readonly structs such as DateTime or TimeSpan then you shouldn't worry.

You can use Distinct and EqualityComparer interface

var list1 = new List<object>() { 1, 2, 3 };
var list2 = new List<object>() { 4, 5, 6 };
var list3 = new List<object>() { 1, 2, 3 };

List<List<object>> mainList = new List<List<object>>() { list1, list2, list3 };

mainList = mainList.Distinct(ListEqualityComparer<object>.Default).ToList();

Equality comparer implementation.

public class ListEqualityComparer<T> : IEqualityComparer<List<T>>
{
    private readonly IEqualityComparer<T> _itemEqualityComparer;

    public ListEqualityComparer() : this(null) { }

    public ListEqualityComparer(IEqualityComparer<T> itemEqualityComparer)
    {
        _itemEqualityComparer = itemEqualityComparer ?? EqualityComparer<T>.Default;
    }

    public static readonly ListEqualityComparer<T> Default = new ListEqualityComparer<T>();

    public bool Equals(List<T> x, List<T> y)
    {
        if (ReferenceEquals(x, y)) return true;
        if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) return false;
        return x.Count == y.Count && !x.Except(y, _itemEqualityComparer).Any();
    }

    public int GetHashCode(List<T> list)
    {
        int hash = 17;
        foreach (var itemHash in list.Select(x => _itemEqualityComparer.GetHashCode(x))
                                     .OrderBy(h => h))
        {
            hash += 31 * itemHash;
        }
        return hash;
    }
}

If your objects does not override Equals and GetHashCode you can make another equality comparer for your items as well and pass it to this equality comparer.

mainList = mainList.Distinct(new ListEqualityComparer<object>(myItemEqualityComparer)).ToList();

where myItemEqualityComparer is for comparing your objects