如何从数组中删除元素

嗨,我正在研究一些遗留代码

for(int i = results.Count-1; i >= 0; i--) { if(someCondition) { results.Remove(results[i]); } } 

对我来说,在迭代循环的同时删除元素似乎是不好的做法,因为你将修改索引。

这是正确的假设吗?

有更好的方法吗? 我想使用LINQ,但我在2.0 Framework中

删除实际上是正确的,因为您将向下归零,只有您已经传递的索引才会被修改。 这段代码实际上会因为另一个原因而中断:它以results.Count开头,但应该从results.Count -1开始,因为数组索引从0开始。

 for(int i = results.Count-1; i >= 0; i--) { if(someCondition) { results.RemoveAt(i); } } 

编辑:

正如所指出的那样 – 你实际上必须处理伪代码中的某种List。 在这种情况下,它们在概念上是相同的(因为列表在内部使用数组)但是如果使用数组,则具有Length属性(而不是Count属性),并且您无法添加或删除项。

使用列表上面的解决方案当然简洁,但对于必须维护代码的人来说可能并不容易理解(即特别是向后遍历列表) – 另一种解决方案可能是首先识别要删除的项目,然后在第二次删除那些项目。

只需用你正在处理的实际类型替换MyType

 List removeItems = new List(); foreach(MyType item in results) { if(someCondition) { removeItems.Add(item); } } foreach (MyType item in removeItems) results.Remove(item); 

它看起来似乎根本不起作用。 如果我们处理固定大小的数组,IList实现应该会失败,请参见此处 。

话虽这么说,如果你正在处理一个可resize的列表(例如List ),为什么要调用Remove而不是RemoveAt? 由于您已经反向导航索引,因此您无需“重新查找”该项目。

我可以建议你当前代码的function更强大的替代品:

您可以从中导出一个新项目,然后在完成后将整个数组替换为“primefaces”操作,而不是一次修改一个项目的现有数组:

简单的方法(没有LINQ,但非常相似):

 Predicate filter = delegate(T item) { return !someCondition; }; results = Array.FindAll(results, filter); // with LINQ, you'd have written: results = results.Where(filter); 

其中Tresults数组中项目的类型。


一个更明确的选择:

 var newResults = new List(); foreach (T item in results) { if (!someCondition) { newResults.Add(item); } } results = newResults.ToArray(); 

通常你不会删除这样的元素,你可以从旧的数组创建一个没有不需要的元素的新数组。

如果您确实从数组/列表中删除元素的路径,则循环应该倒计时而不是向上计数。 (就像你的那样)

几个选项:

 List indexesToRemove = new List(); for(int i = results.Count; i >= 0; i--) { if(someCondition) { //results.Remove(results[i]); indexesToRemove.Add(i); } } foreach(int i in indexesToRemove) { results.Remove(results[i]); } 

或者,您可以复制现有列表,而是从原始列表中删除。

 //temp is a copy of results for(int i = temp.Count-1; i >= 0; i--) { if(someCondition) { results.Remove(results[i]); } }