问题描述
如何从主列表中删除重复的内部列表?
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
问题描述
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