List <List > Remove()方法

我想在列表列表中使用Remove()方法,但它对我不起作用。
简单的例子应该说一切:

List<List> list = new List<List>(); list.Add(new List { 0, 1, 2 }); list.Add(new List { 1, 2 }); list.Add(new List { 4 }); list.Add(new List { 0, 1, }); list.Remove(new List { 1, 2 }); 

如果我使用RemoveAt(1)它工作正常但删除()没有。
显然,此代码返回false的原因相同:

 List l1 = new List(); List l2 = new List(); l1.Add(1); l2.Add(1); bool b1 = l1 == l2; // returns False bool b2 = l1.Equals(l2); // returns False too 

所以在我看来,我不能简单地比较两个列表甚至数组。 我可以使用循环而不是Remove(),但必须有更简单的方法。

提前致谢。

第一种方法:

 List listToRemove = new List { 1, 2 }; list.RemoveAll(innerList => innerList.Except(listToRemove).Count() == 0); 

这也删除了List {2,1}

第二种方法(首选):

 List listToRemove = new List { 1, 2 }; list.RemoveAll(innerList => innerList.SequenceEqual(listToRemove)); 

这将删除包含与提供的列表相同序列的所有列表。

问题是List不会覆盖EqualsGetHashCode ,这是List在尝试查找项目时将使用的。 (事实上​​,它将使用默认的相等比较器,这意味着如果对象实现它,它将使用IEquatable实现,并在必要时回退到object.Equals / GetHashCode )。 当您尝试删除其他对象时, Equals将返回false,默认实现只是比较引用。

基本上你已经编写了一个方法来比较两个列表的相等性,并使用它来查找你想要删除的条目的索引。 然后你将通过索引删除(使用RemoveAt )。 编辑:如上所述, Enumerable.SequenceEqual可用于比较列表。 这不像它可能那样有效,因为当它们可以容易地计算时,最初不检查计数是否相等。 此外,如果需要比较List值,则可以避免对相等比较器的虚方法调用。

另一种方法是首先避免使用List> – 使用List ,其中SomeCustomType 包含 List 。 然后,您可以在类型中实现IEquatable 。 请注意,这也可能允许您在自定义类型中封装适当的逻辑。 我经常发现,根据你有“嵌套”集合类型的类型,自定义类型更有效地封装了内部集合的含义

列表相等是引用相等。 它不会删除列表,除非它与外部列表中的列表具有相同的引用。 您可以创建一个新的类型,实现相等作为集合相等而不是引用相等(或者你也关心顺序?)。 然后你可以制作这种类型的清单。

这根本不起作用,因为你想要删除一个全新的列表( new关键字类型指示这样),而不是你刚刚放在那里的那个。 例如,以下代码创建了两个不同的列表,因为它们不是相同的列表 ,但它们看起来相同:

 var list0 = new List { 1, 2 }; var list1 = new List { 1, 2 }; 

但是,以下内容创建一个列表,但是对同一列表的两个引用:

 var list0 = new List { 1, 2 }; var list1 = list0; 

因此,如果您希望将来使用Remove对其进行操作,则应该保留对您放入的列表的引用,以便:

 var list0 = new List { 1, 2 }; listOfLists.Remove(list0); 

它们是不同的对象。 试试这个:

  List MyList = new List { 1, 2 }; List> list = new List>(); list.Add(new List { 0, 1, 2 }); list.Add(MyList); list.Add(new List { 4 }); list.Add(new List { 0, 1, }); list.Remove(MyList); 

您需要指定要删除的列表的引用:

 list.Remove(list[1]); 

这真的和它一样

 list.RemoveAt(1);