我想在列表列表中使用Remove()方法,但它对我不起作用.
简单的例子应该说一切:
List<List<int>> list = new List<List<int>>();
list.Add(new List<int> { 0, 1, 2 });
list.Add(new List<int> { 1, 2 });
list.Add(new List<int> { 4 });
list.Add(new List<int> { 0, 1, });
list.Remove(new List<int> { 1, 2 });
Run Code Online (Sandbox Code Playgroud)
如果我使用RemoveAt(1)它工作正常但删除()没有.
显然,此代码返回false的原因相同:
List<int> l1 = new List<int>();
List<int> l2 = new List<int>();
l1.Add(1);
l2.Add(1);
bool b1 = l1 == l2; // returns False
bool b2 = l1.Equals(l2); // returns False too
Run Code Online (Sandbox Code Playgroud)
所以在我看来,我不能简单地比较两个列表甚至数组.我可以使用循环而不是Remove(),但必须有更简单的方法.
提前致谢.
Jon*_*eet 11
问题是,List<T>不重写Equals和GetHashCode,这是List<T>试图找到一个项目时,会使用.(实际上,它将使用默认的相等比较器,这意味着IEquatable<T>如果对象实现它,它将使用实现,并在必要时回退到object.Equals/ GetHashCode.).Equals当您尝试删除其他对象时将返回false,默认实现只是比较引用.
基本上你已经编写了一个方法来比较两个列表的相等性,并使用它来查找你想要删除的条目的索引.然后你将通过索引(使用RemoveAt)删除.编辑:如上所述,Enumerable.SequenceEqual可用于比较列表.这不如它可能有效,因为当它们可以容易地计算时,最初不检查计数是否相等.此外,如果您只需要比较List<int>值,则可以避免对等于比较器的虚方法调用.
另一种方法是避免使用List<List<int>>在首位-使用一个List<SomeCustomType>其中SomeCustomType 包括一个List<int>.然后IEquatable<T>,您可以在该类型中实现.请注意,这也可能允许您在自定义类型中封装适当的逻辑.我经常发现,根据你有"嵌套"集合类型的类型,自定义类型更有效地封装了内部集合的含义.
小智 6
第一种方法:
List<int> listToRemove = new List<int> { 1, 2 };
list.RemoveAll(innerList => innerList.Except(listToRemove).Count() == 0);
Run Code Online (Sandbox Code Playgroud)
这也删除了List {2,1}
第二种方法(首选):
List<int> listToRemove = new List<int> { 1, 2 };
list.RemoveAll(innerList => innerList.SequenceEqual(listToRemove));
Run Code Online (Sandbox Code Playgroud)
这将删除包含与提供的列表相同序列的所有列表.
| 归档时间: |
|
| 查看次数: |
4380 次 |
| 最近记录: |