List.RemoveAt(索引)如何工作?

时间:2014-03-20 14:25:49

标签: c#

我们说我有一个列表,消息,有三个项目。我不想循环浏览它们并一次删除一个项目。

for (int i = 0; i < messages.Count; i++)
{ 
    messages.RemoveAt(i);
}

(我已删除了大量不相关的代码)

第一次迭代后剩余的消息会发生什么?它们是移动到另一个索引还是我可以这样删除所有三条消息?

谢谢

8 个答案:

答案 0 :(得分:9)

您删除的索引后面的所有元素的索引将递减。 如果你想通过循环避免这种情况,让它反向运行(从最高索引删除到最低)。

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

或只是使用

messages.Clear()

一次删除所有元素而不关心任何索引。

如果您只想清除列表,使用Clear也会更有效,因为它是O(n)操作。 RemoveAt也是O(n),但在另一个O(n)循环内部使其成为O(n ^ 2) - 并不是因为在你的例子中提到了3个元素,而是在讨论更大的列表时肯定会有所作为。

答案 1 :(得分:3)

在您的代码中,只需拨打messages.Clear();即可。无需单独删除每个元素。

您的代码将跳过所有其他元素,因为它会删除它们,直到不再满足for循环的条件。它将删除索引0和2处的元素,因为您说您的集合有三个元素。

让我们逐步完成您的算法:

最初,该列表有三个项目,列出其索引:0:“Hello”,1:“World”,2:“Foo”。

你的循环删除索引0处的元素。列表现在看起来像这样:

0:“世界”,1:“Foo”

然而,你的循环再次执行,因为i现在等于1和1 < 2。然后删除索引1处的元素:

0:“世界”

i增加到2并且不再满足条件(i不小于1)。您的列表现在包含以前的第二个元素。

答案 2 :(得分:3)

您需要迭代向后

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

因为在您当前的循环中,如果您的列表包含3个项目,您将被留下一次。

如果您要从列表中删除所有项目,则可以使用方法List<T>.RemoveAll Method

答案 3 :(得分:1)

他们搬了,see MSDN on List<T>.RemoveAt method

  

当您调用RemoveAt删除项目时,中的剩余项目   列表重新编号以替换已删除的项目。例如,如果你   删除索引3处的项目,索引4处的项目移动到3   位置。

要删除所有元素Clear method更合适。

答案 4 :(得分:0)

通过反向循环..

  for(int i = messages.Count - 1; i >= 0 ; i--) {
    messages.RemoveAt(i);

}

答案 5 :(得分:0)

.NET Reference Source具有以下RemoveAt方法定义:

public void RemoveAt(int index) 
{
    if ((uint)index >= (uint)_size)             
        ThrowHelper.ThrowArgumentOutOfRangeException();            
    Contract.EndContractBlock();

    _size--;

    if (index < _size) 
        Array.Copy(_items, index + 1, _items, index, _size - index);

    _items[_size] = default(T);
    _version++;
}

正如您所看到的 - 如果您删除的项目不是最后一次复制数组项目(从索引+ 1到结束移动的所有项目)。因此,在您的情况下,最好从最后删除项目以避免每次迭代时进行数组复制:

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

如果你想在没有额外逻辑的情况下删除它们,只需调用messages.Clear() - 在这种情况下,内部数组刚刚清除,大小设置为零。

答案 6 :(得分:0)

您可以将其更改为始终删除第一个

List<string> messages = new List<string>();
messages.Add("a"); 
messages.Add("b");
messages.Add("c");

for (int i = 0; i < messages.Count; i++)
{
     messages.RemoveAt(0);
}

或在一个陈述中清除整个列表

messages.Clear()

答案 7 :(得分:0)

与其他帖子一样,您需要向后迭代

您有很多解决方案可以删除这些项目

messages.Clear(); 

while(messages.Count != 0){
    message.RemoveAt(0);
}