我想在列表列表中使用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 });
如果我使用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
所以在我看来,我不能简单地比较两个列表甚至数组。我可以使用循环而不是Remove(),但必须有更简单的方法。
提前致谢。
答案 0 :(得分: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>
。请注意,这也可能允许您在自定义类型中封装适当的逻辑。我经常发现,根据你有“嵌套”集合类型的类型,自定义类型更有效地封装了内部集合的含义。
答案 1 :(得分:6)
第一种方法:
List<int> listToRemove = new List<int> { 1, 2 };
list.RemoveAll(innerList => innerList.Except(listToRemove).Count() == 0);
这也删除了List {2,1}
第二种方法(首选):
List<int> listToRemove = new List<int> { 1, 2 };
list.RemoveAll(innerList => innerList.SequenceEqual(listToRemove));
这将删除包含与提供的列表相同序列的所有列表。
答案 2 :(得分:4)
列表相等是引用相等。它不会删除列表,除非它与外部列表中的列表具有相同的引用。你可以创建一个新的类型来实现相等作为集合相等而不是引用相等(或者你也关心顺序?)。然后你可以制作这种类型的清单。
答案 3 :(得分:2)
这根本不起作用,因为你想要删除一个全新的列表(new
关键字指示这样的列表),而不是你刚刚放在那里的那个。例如,以下代码创建两个不同的列表,因为它们不是相同的列表,但是它们看起来相同:
var list0 = new List<int> { 1, 2 };
var list1 = new List<int> { 1, 2 };
但是,以下内容创建了一个列表,但是对相同列表的两个引用:
var list0 = new List<int> { 1, 2 };
var list1 = list0;
因此,如果您希望将来使用Remove
对其进行操作,则应该保留对您放入的列表的引用,以便:
var list0 = new List<int> { 1, 2 };
listOfLists.Remove(list0);
答案 4 :(得分:1)
它们是不同的对象。试试这个:
List<int> MyList = new List<int> { 1, 2 };
List<List<int>> list = new List<List<int>>();
list.Add(new List<int> { 0, 1, 2 });
list.Add(MyList);
list.Add(new List<int> { 4 });
list.Add(new List<int> { 0, 1, });
list.Remove(MyList);
答案 5 :(得分:0)
您需要指定要删除的列表的引用:
list.Remove(list[1]);
,实际上与
相同list.RemoveAt(1);