如何从Foreach循环中的列表动态删除项目

时间:2016-05-04 07:38:41

标签: c# asp.net-mvc list foreach

我们很容易看到代码抛出错误的原因。

Error:{"Collection was modified; enumeration operation may not execute."}

但是必须有一种方法可以做到这一点,使用foreach(而不是for),使用List<>。请不要告诉我深刻复制方法,如制作

var cloneList = NumberList.ToList()

并从中删除项目。因为如果我们有100万个元素,我们将会有200万个元素用于删除等等。我不需要这个。

代码段在这里;

public class HomeController : Controller
{
    // GET: Home
    public ActionResult Index()
    {
        var numberList = new List<int>();
        numberList.AddRange(new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 });
        var totalNumber = 0;
        foreach (var item in numberList)
        {
            totalNumber += item;
            if (item == 5)
            {
                numberList.Remove(item);
            }
        }
        return View(totalNumber);
    }
}

请帮我讲一下这个脑燃烧器代码片段。

谢谢。

更新:问题不在于在最后一点获取List元素的Sum()。问题的核心是,如何在foreach循环中从列表中删除项目。

5 个答案:

答案 0 :(得分:0)

您在foreach循环中修改了您的集合,因此在下一次迭代中,集合元素编号更改并且foreach无法迭代,请尝试此操作

public ActionResult Index()
{
    var numberList = new List<int>();
    numberList.AddRange(new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 });
    var totalNumber = 0;
    var numberListTemp = numberList;
    foreach (var item in umberListTemp)
    {
        totalNumber += item;
        if (item == 5)
        {
            numberList.Remove(item);
        }
    }
    return View(totalNumber);
}

答案 1 :(得分:0)

首先计算总数,然后删除项目:

var totals = numberList.Sum();  
numberList.RemoveAll(i=>i==5);

答案 2 :(得分:0)

如果双重迭代和深层复制是问题,这就是我的方法:

        ...
        var numberList = new List<int>();
        numberList.AddRange(new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 });
        var totalNumber = 0;
        foreach (var item in YieldingNotFive(numberList))
        {
            totalNumber += item;
        }
        ...

    private IEnumerable<int> YieldingNotFive(List<int> numberList)
    {
        foreach (int item in numberList)
        {
            if (item != 5)
            {
                yield return item;
            }
        }
        yield break;
    }

    var numberList = new List<int>();
    numberList.AddRange(new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 });
    var totalNumber = 0;
    foreach (var item in numberList.Where(x => x != 5))
    {
        totalNumber += item;
    }

答案 3 :(得分:0)

尝试为循环添加一个计数器,当你的条件到达时删除该元素。

public class HomeController : Controller
{
    // GET: Home
    public ActionResult Index()
    {
        var numberList = new List<int>();
        numberList.AddRange(new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 });
        var totalNumber = 0;
        var count = 0;
        foreach (var item in numberList)
        {
            totalNumber += item;
            if (item == 5)
            {
                numberList.Remove(count);
            }
            count = count + 1;
        }
        return View(totalNumber);
    }
}

但我不知道从索引中删除的函数的名称。

答案 4 :(得分:0)

我找到了答案。从下面您可以看到tradinional foreach和Parallel.ForEach之间的性能细节。

我希望这会有用。

class Program
{
    static void Main(string[] args)
    {           
        List<string> colorList = new List<string>();
        colorList.AddRange(new List<string>() {
                                  "1. Red",
                                  "2. Green",
                                  "3. Blue",
                                  "4. Yellow",
                                  "5. White",
                                  "6. Black",
                                  "7. Violet",
                                  "8. Brown",
                                  "9. Orange",
                                  "10. Pink"
        });
        Console.WriteLine("Traditional foreach loop\n");
        //start the stopwatch for "for" loop
        var sw = Stopwatch.StartNew();
        foreach (string color in colorList)
        {
            Console.WriteLine("{0}, Thread Id= {1}", color, Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(10);
        }
        Console.WriteLine("Foreach loop execution time = {0} seconds\n", sw.Elapsed.TotalSeconds);

        //-------------------------------------------------------------------------------------------------------------------------------------------------------

        Console.WriteLine("Using Parallel.ForEach");
        //start the stopwatch for "Parallel.ForEach"
        sw = Stopwatch.StartNew();
        int index = 0;
        Parallel.ForEach(colorList, (color, state) =>
        {

            ++index;
            if (index > colorList.Count - 1)
            {
                state.Stop();
            }

            Console.WriteLine("{0}, Thread Id= {1}", color, Thread.CurrentThread.ManagedThreadId);
            if (color == "2. Green")
            {
                colorList.RemoveRange(3, 2);
            }
            Thread.Sleep(10);
        }
        );
        Console.WriteLine("Parallel.ForEach() execution time = {0} seconds", sw.Elapsed.TotalSeconds);
        Console.Read();
    }
}