简体   繁体   English

在条件下从List <>中删除对象

[英]Remove object from List<> on condition

I am creating an ant simulation program where ants travel around and collect food and bring it to the nest. 我正在创建一个蚂蚁模拟程序,使蚂蚁四处旅行并收集食物并将其带到巢中。 When a certain number of ants have collected from the food I want the food source to disappear. 当从食物中收集到一定数量的蚂蚁时,我希望食物来源消失。 I have a separate class for antObject, foodObject and nestObject. 我有一个用于antObject,foodObject和nestObject的单独的类。

I have a 'int foodleft = 25' variable in my stationaryFood class. 我的fixedFood类中有一个'int foodleft = 25'变量。 The foodobjects are placed onto the screen when the user clicks, and are immediately added to a list object 'foodList'. 当用户单击时,食物对象将放置在屏幕上,并立即添加到列表对象“ foodList”。 A draw method draws all the objects in the list. draw方法绘制列表中的所有对象。 I cannot figure out how to make the specific food object disappear when its 'foodLeft' variable hits 0! 我无法弄清楚当'foodLeft'变量变为0时如何使特定食物对象消失!

Here is my draw method in my stationaryFood class - 这是我的fixedFood类中的绘制方法-

  public void Draw(SpriteBatch spriteBatch, List<stationaryFood> foodlist)
    {
        foreach (stationaryFood food in foodlist)
        {
            spriteBatch.Draw(foodImage, foodBoundingRectangle, foodColor);                                                              //draw each food object in foodList
        }
    }

And here is my attempted solution to the problem in my main 'game1' class in the update method 这是我尝试在update方法中的主“ game1”类中解决此问题的方法

  if (foodList.Count > 0)
        {
            foreach (stationaryFood f in foodList)
            {
                if (f.FoodLeft == 0)
                {
                    foodList.Remove(f);


                }
            }
        }

However this does not work! 但是,这不起作用! I get an 'unhandled invalid operation error'. 我收到“未处理的无效操作错误”。

In my draw method in my main game1 class I have this 在我的主要game1类的draw方法中,我有这个

        foreach (stationaryFood f in foodList)
        {
            f.Draw(spriteBatch, foodList);
        }

Can anybody see where I am going wrong? 有人可以看到我要去哪里错吗?

You're modifying the collection as you're iterating through it, hence why you're getting an exception. 您在遍历集合时正在修改集合,因此为什么会遇到异常。 In your case, instead of this: 在您的情况下,请执行以下操作:

foreach (stationaryFood f in foodList)
{
    if (f.FoodLeft == 0)
    {
        foodList.Remove(f);
    }
}

Do this instead (assuming it's available in XNA): 而是这样做(假设它在XNA中可用):

foodList.RemoveAll(x => x.FoodLeft == 0)

If it isn't, you can look at the answer in this question for an alternative. 如果不是,您可以查看问题的答案以寻求替代方案。

George Howarth's answer will work perfectly fine. 乔治·霍华斯的答案将非常有效。

If you are uncomfortable with lambda expressions you could try reverse iteration : 如果您对lambda表达式不满意,可以尝试反向迭代

foreach (stationaryFood f in foodList.Reverse<stationaryFood>())
{
    if (f.FoodLeft == 0)
    {
        foodList.Remove(f);
    }
}

Reverse iteration allows us to loop through a collection and remove items at the same time. 反向迭代使我们可以遍历一个集合并同时删除项目。

Preamble: 前言:

Game programming is a good way to get started with C#, but I would advise to read more into the basic constructs like for , foreach and the language conventions. 游戏编程是开始使用C#的一种好方法,但是我建议您进一步阅读诸如forforeach和语言约定之类的基本结构。

The first five modules in the Microsoft Virtual Academcy Programming in C# Jump Start will greatly increase your understanding of the language. C#快速入门中的Microsoft Virtual Academcy Programming中的前五个模块将极大地增进您对该语言的理解。

Answer: 回答:

I could not see a reason to use foodlist in the stationaryFood class. 我看foodliststationaryFood foodlist类中使用foodlist的原因。 This will draw overlapped textures which is pointless. 这将绘制重叠的纹理,这毫无意义。

public void Draw(SpriteBatch spriteBatch)
{
    spriteBatch.Draw(foodImage, foodBoundingRectangle, foodColor);
}

You can make a method which will remove items from the list. 您可以创建一种从列表中删除项目的方法。

private void RemoveFood(List<stationaryFood> foodlist)
{
    var foodToRemove = new List<stationaryFood>();

    foreach(var f in foodlist)
    {
        if(f.FoodLeft == 0)
        {
            foodToRemove.Add(f);
        }
    }

    foreach(var f in foodToRemove)
    {
        foodlist.Remove(f);
    }
}

Later on when you learn about lambdas it can be simplified to: 稍后,当您了解lambda时,可以将其简化为:

private void RemoveFood(List<stationaryFood> foodlist)
{
    foodlist.RemoveAll(food => food.FoodList == 0);
}

You can add this in the Update method. 您可以在Update方法中添加它。

if (foodList.Count > 0)
{
    RemoveFood(fooList);
}

And change the logic in the Draw method. 并更改Draw方法中的逻辑。

if (foodlist.Count > 0)
{
    foreach(var f in foodlist)
    {
        f.Draw(spriteBatch);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM