我有一个列表,其中包含一些字符串类型的项目.
List<string> lstOriginal;
Run Code Online (Sandbox Code Playgroud)
我有另一个列表,其中包含应从第一个列表中删除的id.
List<int> lstIndices;
Run Code Online (Sandbox Code Playgroud)
我试图用RemoveAt()方法完成这项工作,
foreach(int indice in lstIndices)
{
lstOriginal.RemoveAt(indice);
}
Run Code Online (Sandbox Code Playgroud)
但它崩溃并且说我"索引超出范围".
das*_*ght 31
您需要对要从最大到最小返回的索引进行排序,以避免在错误的索引处删除某些内容.
foreach(int indice in lstIndices.OrderByDescending(v => v))
{
lstOriginal.RemoveAt(indice);
}
Run Code Online (Sandbox Code Playgroud)
这是为什么:让我们说有五个项目的清单,并且希望在索引中删除项目2和4.如果首先删除该项2,则索引处的项目4将位于索引处3,索引4将不再位于列表中(导致您的异常).如果你倒退,所有索引都会在你准备删除相应项目的那一刻.
你如何填写指数列表?RemoveAll您可以使用更有效的方法.例如,而不是这样:
var indices = new List<int>();
int index = 0;
foreach (var item in data)
if (SomeFunction(data))
indices.Add(index++);
//then some logic to remove the items
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
data.RemoveAll(item => SomeFunction(item));
Run Code Online (Sandbox Code Playgroud)
这最大限度地减少了将项目复制到阵列中的新位置; 每个项目只复制一次.
您还可以在上面的示例中使用方法组转换,而不是lambda:
data.RemoveAll(SomeFunction);
Run Code Online (Sandbox Code Playgroud)
之所以发生这种情况,是因为当你从列表中删除一个项目时,每个项目的索引会有效地减少一个,所以如果你按照增加的索引顺序删除它们,并且原始列表末尾附近的某些项目是删除后,这些索引现在无效,因为删除前面的项目后列表会变短.
最简单的解决方案是按递减顺序对索引列表进行排序(最高索引优先),然后对其进行迭代.
for (int i = 0; i < indices.Count; i++)
{
items.RemoveAt(indices[i] - i);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
23509 次 |
| 最近记录: |