c# List -在循环/迭代时删除项
本文关键字:迭代 删除 循环 List | 更新日期: 2023-09-27 18:07:59
假设我有以下代码片段:
var data=new List<string>(){"One","Two","Three"};
for(int i=0 ; i<data.Count ; i++){
if(data[i]=="One"){
data.RemoveAt(i);
}
}
下面的代码抛出异常。
我的问题是什么是最好的方法来避免这个异常和删除元素,而循环?
如果你需要删除元素,那么你必须向后迭代,这样你就可以从列表的末尾删除元素:
var data=new List<string>(){"One","Two","Three"};
for(int i=data.Count - 1; i > -1; i--)
{
if(data[i]=="One")
{
data.RemoveAt(i);
}
}
然而,在LINQ中有更有效的方法来做到这一点(如其他答案所示)。
您可以使用List<T>.RemoveAll
来处理此问题:
data.RemoveAll(elem => elem == "One");
您也可以使用向前移动循环,如:
var data = new List<string>() { "One", "Two", "Three", "One", "One", "Four" };
for (int i = 0; i < data.Count; i++)
{
if (data[i] == "One")
{
data.RemoveAt(i--);
}
}
这行data.RemoveAt(i--);
在循环结束时停止迭代变量的增量效果,以防项目从列表中删除。
它将从index中移除当前迭代值处的项,然后移除该项后,迭代器将被设置为比当前值少一个的值。在循环结束时,循环体中的增量将把它移动到下一个有效索引。
这是一个工作的dotfiddle
(请注意,我个人在这种情况下使用反向循环,因为在我看来,它们更容易理解,这里的答案只是为了显示另一种实现它的方式)。
我碰巧遇到一个简单的解决方案,使用foreach
和.ToArray()
var data=new List<string>(){"One","Two","Three"};
foreach ( var d in data.ToArray()){
if(d =="One"){
data.Remove(d);
}
}
您可以尝试使用ChrisF的反向迭代方法来删除您的条目。
你也可以简单地:
List.Remove("One");
或:
List.RemoveAll(i => i == "One"); // removes all instances
并完成它。在集合上迭代以删除单个项是没有意义的。
为什么不直接递减迭代器变量呢?
var data=new List<string>(){"One","Two","Three"};
for(int i=0 ; i<data.Count ; i++){
if(data[i]=="One"){
data.RemoveAt(i);
i--; // <<<<<<<<<<<
}
}
这是一个肮脏的把戏,我想知道它会受到什么批评?
var data=new List<string>(){"One","Two","Three"};
foreach (string itm in (data.ToArray()))
{
if string.Compare(name, "one", true) == 0) data.Remove(name);
}
var data=new List<string>(){"One","Two","Three"};
for(int i=0; i<data.Count; ){
if(data[i]=="One") data.RemoveAt(i);
else ++i;
}
下面的一般解决方案复制列表并处理负索引:
foreach (void item_loopVariable in MyList.ToList) {
item = item_loopVariable;
}
var data = new List<string>() { "One", "Two", "Three" };
data.RemoveAll(p=>p=="One");
可以使用Stack class
Stack<string> myStack = new Stack<string>();
foreach (var item in Enumerable.Range(1,1001))
myStack.Push("Str " + item.ToString());
while (myStack.Any())
Console.WriteLine("Now {0} items in Stack, removed item is {1}",myStack.Count,myStack.Pop());
Console.ReadKey();
我必须从列表中删除多个项目。我重新初始化了列表计数。还有其他更好的选择吗?
for (int i = dtList.Count - 1; dtList.Count > 0; )
{
DateTime tempDate = dtList[i].Item1.Date;
var selectDates = dtList.FindAll(x => x.Item1.Date == tempDate.Date);
selectDates.Sort((a, b) => a.Item1.CompareTo(b.Item1));
dtFilteredList.Add(Tuple.Create(selectDates[0].Item1, selectDates[0].Item2));
dtList.RemoveAll(x => x.Item1.Date == tempDate.Date);
i = dtList.Count - 1;
}
List<string> list = new List<string>();
list.Add("sasa");
list.Add("sames");
list.Add("samu");
list.Add("james");
for (int i = list.Count - 1; i >= 0; i--)
{
list.RemoveAt(i);
}