从c#中的列表列表中删除重复的内部列表

我为这个含糊不清的标题道歉。 我不能同时保持清晰和简洁。 所以随意改变它。

我有一个很大的列表,其中包含其他几个列表。 这些内部列表包含Column对象。

List<List> listOfAllColumns; 

假设我的内部列表包含不同的Column对象,如下所示:

 list1 = {c1, c1, c2} list2 = {c1, c2, c1} list3 = {c2, c3} list4 = {c1,c1, c2} 

大列表包含以下列表:listOfAllColumns = {list1,list2,list3,list4}

现在我想要一个从listOfAllColumns列表中删除重复列表的方法。 例如,它将查看上面的列表并删除list4。

 list1: c1,c1,c2 list2: c1,c2,c1 list3: c2,c3 list4: c1,c1,c2 (it is equal to list1 so it is a duplicate) 

这是我的代码:

 public class ColumnList { public void RemoveDuplicateColumnTypes() { Column c1 = new Column() { SectionName = "C50", StirrupType = "Tie" }; Column c2 = new Column() { SectionName = "C50", StirrupType = "Spiral" }; Column c3 = new Column() { SectionName = "C40", StirrupType = "Tie" }; List list1 = new List() { c1, c1, c2 }; List list2 = new List() { c1, c2, c1 }; List list3 = new List() { c2, c3 }; List list4 = new List() { c1, c1, c2 }; List<List> listOfAllColumns = new List<List>() { list1, list2, list3, list4 }; var result = listOfAllColumns.Distinct(); } } class Column { public string SectionName; public string StirrupType; public int StirrupSize; public double StirrupSpacing; } 

顺便说一下,顺序很重要,例如{c1,c2,c1}与{c2,c1,c1}不同。

我将实现一个自定义IEqualityComparer> ,您可以将其用于Distinct

 public class ColumnListComparer : IEqualityComparer> { public bool Equals(IEnumerable x, IEnumerable y) { if (x == null || y == null) return false; if (object.ReferenceEquals(x, y)) return true; return x.SequenceEqual(y); } public int GetHashCode(IEnumerable obj) { unchecked { int hash = 17; foreach(Column col in obj) { hash = hash * 23 + (col == null ? 0 : col.GetHashCode()); } return hash; } } } 

现在这个工作:

 var result = listOfAllColumns.Distinct(new ColumnListComparer()); 

您还需要在类Column重写Equals + GetHashCode

 public class Column { public string SectionName; public string StirrupType; public int StirrupSize; public double StirrupSpacing; public override bool Equals(object obj) { Column col2 = obj as Column; if(col2 == null) return false; return SectionName == col2.SectionName && StirrupType == col2.StirrupType && StirrupSize == col2.StirrupSize && StirrupSpacing == col2.StirrupSpacing; } public override int GetHashCode() { unchecked { int hash = 17; hash = hash * 23 + (SectionName ?? "").GetHashCode(); hash = hash * 23 + (StirrupType ?? "").GetHashCode(); hash = hash * 23 + StirrupSize.GetHashCode(); hash = hash * 23 + StirrupSpacing.GetHashCode(); return hash; } } } 

您需要的是能够比较不同序列的IEqualityComparer 。 这并不是特别难,因为它还有一种比较其中项目的方法:

 public class SequenceComparer : IEqualityComparer> { private IEqualityComparer comparer; public SequenceComparer(IEqualityComparer comparer = null) { this.comparer = comparer ?? EqualityComparer.Default; } public bool Equals(IEnumerable x, IEnumerable y) { return x.SequenceEqual(y, comparer); } public int GetHashCode(IEnumerable sequence) { unchecked { int hash = 19; foreach (var item in sequence) hash = hash * 79 + comparer.GetHashCode(item); return hash; } } } 

现在你需要做的就是创建一个IEqualityComparer ,它能够比较两个列对象(通过你想要的任何有意义的方式,可能是默认的实现是不够的)。

然后你可以将它们传递给Distinct

 var query = listOfAllColumns.Distinct( new SequenceComparer(new ColumnComparer()));