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
不会覆盖Equals
和GetHashCode
,这是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);