C# for循环中的更改列表
我正在尝试修改for值中的列表C# for循环中的更改列表,c#,list,for-loop,C#,List,For Loop,我正在尝试修改for值中的列表 for (int i = 0; i < theList.Count; i++) { if(someCircunstances) theList.remove(component); else theList.add(component); } for(int i=0;iArgumentOutOfRangeException 所以为了解决这个问题,我建议您将其拆分为两个for循环: for (int i = t
for (int i = 0; i < theList.Count; i++) {
if(someCircunstances)
theList.remove(component);
else
theList.add(component);
}
for(int i=0;i
使用此方法,我得到一个ArgumentOutOfRangeException
。
有什么方法可以做到这一点吗?在迭代列表时对列表进行变异也是一种不好的做法 这是另一种选择:
theList.RemoveAll(someCircunstances);
可以通过向后迭代并使用索引而不是项来解决此问题:
for (int i = list.Count - 1; i > 0; i--)
{
if(condition)
list.RemoveAt(i);
else
list.Add(component);
}
一些解释:当您迭代集合时,不应该更改范围中的项。迭代器将检测到并抛出(在foreach
的情况下,您必须使用列表的副本)。但是如果使用索引(RemoveAt()
method),并且在向后迭代时,对于下一次迭代,您是安全的,范围不包括已删除的项<代码>添加()正在添加到末尾,因此新项永远不在范围内
我将再添加几个解决方案,您自己决定哪一个更好: 先复制的经典foreach:
foreach(var item in list.ToArray()) // imho `ToArray` is better than `ToList`
if(condition)
list.Remove(item);
else
list.Add(component);
新名单如下:
var result = new List<...>();
foreach(var item in list)
result.Add(condition ? component : item); // not sure here, but should give you idea
list = result;
var result=newlist();
foreach(列表中的变量项)
结果.添加(条件?组件:项);//这里不确定,但应该给你一个主意
列表=结果;
由于索引从0开始,您将获得一个超出范围的异常
如上所述,一种解决方案是从list.count中删除1,另一种解决方案是在1而不是0处启动i
试想一下:如果列表中有1个元素,那么该元素的索引为0;如果有100个元素,那么第100个元素的索引为99
您认为列表像:[1][2][3],而实际上它是[0][1][2]这里的问题是,您正在从列表中删除值,然后使用已删除的索引再次遍历它->
ArgumentOutOfRangeException
所以为了解决这个问题,我建议您将其拆分为两个for循环:
for (int i = theList.Count - 1; i >= 0; i--) {
if(someCircunstances)
theList.remove(component);
}
for (int i = 0; i < theList.Count; i++) {
if(someCircunstances)
theList.add(component);
}
for(int i=list.Count-1;i>=0;i--){
if(某些循环)
列表。移除(组件);
}
对于(int i=0;i
我同意塔马斯的观点,即在迭代时不要改变列表,还有另一种方法可以达到你的目的
List<someType> ToRemove=new List<someType>() ; //some type is same type as theList is
List<someType> ToAdd=new List<someType>();
for (int i = 0; i < theList.Count; i++) {
if(someCircunstances)
ToRemove.add(component);
else
ToAdd.add(component);
}
theList=((theList.Except(ToRemove)).Concat(ToAdd)).ToList();
List-ToRemove=新列表()//某些类型与列表的类型相同
List ToAdd=新列表();
对于(int i=0;i
根据注释,您需要能够为新创建的项目应用相同的逻辑
您需要这样做:
public void DoIt(List<MyObject> theList)
{
List<MyObject> items_to_remove = new List<MyObject>();
List<MyObject> items_to_add = new List<MyObject>();
for (int i = 0; i < theList.Count; i++)
{
if (someCircunstances)
items_to_remove.Add(....); //Remove some existing item
else
items_to_add.Add(....); //Add a new item
}
if(items_to_remove.Count > 0)
items_to_remove.ForEach(x => theList.Remove(x));
if (items_to_add.Count > 0)
{
DoIt(items_to_add); //Recursively process new objects
theList.AddRange(items_to_add);
}
}
public void DoIt(列表)
{
List items_to_remove=新建列表();
列表项_to_add=新列表();
对于(int i=0;i0)
items_to_remove.ForEach(x=>list.remove(x));
如果(项添加到项计数>0)
{
DoIt(items_to_add);//递归地处理新对象
列表添加范围(项添加到项添加);
}
}
其思想是将要添加的项和要删除的项插入到它们自己的列表中
然后在迭代之后,删除需要删除的项
之后,您需要添加要添加的项目。但是,在这样做之前,您需要对它们运行相同的逻辑,这就是递归调用的解释
请注意,我使用的是
MyObject
,因为我不知道您列表的类型。使用您正在使用的任何类型。如果您可以使用循环的当前索引从lst中删除项目,您可以像这样轻松地执行此操作:
using System;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
var numbers = Enumerable.Range(1, 20).ToList();
var rng = new Random();
for (int i = 0; i < numbers.Count; ++i)
{
if (rng.NextDouble() >= 0.5) // If "someCircumstances"
{
numbers.Add(numbers[i]*2);
}
else
{
// Assume here you have some way to determine the
// index of the item to remove.
// For demo purposes, I'll just calculate a random index.
int index = rng.Next(0, numbers.Count);
if (index >= i)
--i;
numbers.RemoveAt(index);
}
}
Console.WriteLine(string.Join("\n", numbers));
}
}
}
使用系统;
使用System.Linq;
命名空间控制台应用程序1
{
班级计划
{
静态void Main()
{
var numbers=Enumerable.Range(1,20).ToList();
var rng=新随机数();
对于(int i=0;i=0.5)//if“某些情况”
{
编号。添加(编号[i]*2);
}
其他的
{
//假设你有办法确定
//要删除的项的索引。
//出于演示目的,我将只计算一个随机索引。
int index=rng.Next(0,number.Count);
如果(索引>=i)
--一,;
数字。删除(索引);
}
}
Console.WriteLine(string.Join(“\n”,数字));
}
}
}
这也将遍历添加到列表末尾的所有数字。numbers.Count的值在每次迭代时都会重新计算,因此当它发生变化时,循环将被适当地扩展
(主题外)额外问题:在上面的代码中,当循环退出时,列表的平均大小是多少?最大尺寸是多少?可能您没有正确的组件的引用。你是怎么理解这个引用的?我知道,当第五个iterarion出现时它崩溃了,我调试了一个实例,发现崩溃与删除和添加函数无关。你需要将for循环从Count-1反转为0,你的意思是for(int I=theList.Count-1;I<0;I++)
在迭代过程中添加的项目如何?你想对它们进行迭代吗?我需要从列表中删除“坏”节点,我无法将其全部删除。塔马斯是对的,只需编写类似列表的内容。RemoveAll(item=>SomeCircunStatesMatch(item));如果你想这么做,我