Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by ezlockwo · Apr 17, 2013 at 04:51 PM · errorlistremove

Removing items from a list while iterating through it?

So what I'm doing is iterating through a list which is displaying a set of boxes representing each item in the list. Each of those boxes representing the items has a button in it that lets the user delete that item from the list (any item at any place in the list). Of course, this is throwing an exception since I'm removing an item from a list while iterating it.

The only answer I've seen so far involves iterating backwards through the list and then deleting within the for loop. I've tried this solution and it wasn't preventing the exception when I remove an item, so here I am trying to figure out what I can do to get around this error.

I can post the old code if someone wants to see what I tried to do with the backward iteration solution.

     using UnityEngine;
     using System.Collections;
      
     public class SceneManager : MonoBehaviour {
         string name;
         string gender;
         string type;
         public bool showCreateActor = false;
         public ArrayList actors;
          
         void Start () {
             actors = new ArrayList();
             name = string.Empty;
             gender = string.Empty;
             type = string.Empty;
         }
          
         public void removeActor(ActorGUI self){
             actors.Remove(self);
         }
      
     void ActorWindowSide(int windowID) {
         
         if(GUILayout.Button ("Add Actor", GUILayout.Width (100),GUILayout.Height (30))){
             showCreateActor = !showCreateActor;
         }
         GUILayout.BeginVertical();
         //the loop in question
         foreach(ActorGUI actor in actors){
             actors[i].Draw();
         }
         GUILayout.EndVertical();
     }
      
     public void createNewActor(int windowID)
     {
         GUI.Label (new Rect(5f,30f,75f,20f), "Name: ");
         GUI.Label (new Rect(5f,55f,75f,20f), "Gender: ");
          
         name = GUI.TextField(new Rect (85f,30f,100f,25f), name, 25);
         gender = GUI.TextField(new Rect (85f,55f,100f,25f), gender, 10);
          
         if(GUI.Button (new Rect(85f, 260f, 110f, 30f), "Create Actor")){
             ActorGUI a = gameObject.AddComponent("ActorGUI") as ActorGUI;
             a.setActorNumber (actors.Count);
             a.setActorName (name);
             a.setActorGender (gender);
      
             actors.Add(a);
      
             showCreateActor = !showCreateActor;
             name = string.Empty;
             gender = string.Empty;
         }
      
         if(GUI.Button (new Rect(205f, 260f, 110f, 30f), "Cancel")){
             showCreateActor = !showCreateActor;
             name = string.Empty;
             gender = string.Empty;
         }
     }
 }
      
     using UnityEngine;
     using System;
     using System.Collections;
      
     public class ActorGUI : MonoBehaviour {
         public int actorNumber;
         public string actorName;
         public string actorGender;
         private SceneManager mySceneManager;
         private ActorGUI self;
          
         void Start () {
             mySceneManager = gameObject.GetComponent("SceneManager") as SceneManager;
         }
          
         public void setActorNumber(int i) {
             actorNumber = i;
         }
          
         public void setActorName(string name){
             actorName = name;
         }
          
         public void setActorGender(string gender){
             actorGender = gender;
         }
          
         public void setSelf(ActorGUI me){
             self = me;
         }
          
         public void Draw(){
             GUILayout.BeginVertical("box");
             GUILayout.BeginHorizontal();
             if(GUILayout.Button (actorName,GUILayout.Height(30))){
          
             }
             if(GUILayout.Button ("X", GUILayout.Width(30),GUILayout.Height(25))){
                 mySceneManager.removeActor(self);
             }
             GUILayout.EndHorizontal();
             GUILayout.EndVertical();
         }
     }
Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Fattie · Mar 15, 2014 at 05:33 PM 0
Share

the easiest way is to GO BAC$$anonymous$$WARDS. it's a a basic general program$$anonymous$$g trick.

3 Replies

· Add your reply
  • Sort: 
avatar image
11
Best Answer

Answer by whydoidoit · Apr 17, 2013 at 06:14 PM

You cannot remove an item from a List that you are iterating over with foreach. You have three choices:

  • a backwards running for..next loop and RemoveAt

  • make a copy of the list your are iterating (with Linq.ToList())

  • make a list of the things to remove and then RemoveRange them after the list.

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image whydoidoit · Apr 17, 2013 at 06:20 PM 0
Share

Now you've updated your code it would appear that adding the actor to a "removals" list would be the most efficient method (Linq would be easier to write but it would cause garbage collection).

Why are you defining a variable called self which is exactly the same as this?

avatar image whydoidoit · Apr 17, 2013 at 06:21 PM 1
Share

Also don't use ArrayList - use a generic List< ActorGUI> which is faster and typesafe.

avatar image ezlockwo · Apr 17, 2013 at 06:35 PM 0
Share

I've tried both List<> and ArrayList, this just happens to be the version w/ ArrayList.

I didn't use this because I forgot I could, thanks for the re$$anonymous$$der.

The Linq.ToList() method sounds better (or at least faster), I'm not that concerned about garbage collection at the moment, I'll probably end up giving both a try. Thanks.

avatar image whydoidoit · Apr 17, 2013 at 06:42 PM 0
Share

So that would look like

  using System.Linq;

  ...


  foreach(ActorGUI actor in actors.ToList())
avatar image
4

Answer by Dracorat · Apr 17, 2013 at 04:59 PM

I don't see the loop in your code. I checked three times.

But you had the right idea, you have to iterate through it backward. You can remove items as you go.

You cannot remove items from a for-each - it has to be a for(int variable ... type loop.

If you want to post the code that's failing while you try to backward iterate, I'll look again.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ezlockwo · Apr 17, 2013 at 06:11 PM 0
Share

Oh hmm, I had it all grouped together, I guess it got missed in the copy/paste. Fixing now...

avatar image
4

Answer by polysoft3D · Feb 23, 2020 at 11:44 PM

 for(int i =0;i<"yourlist".Count;i++)
 {
       if("yourlist"[i] ==  "condition to remove")
       {
            "yourlist".removeAt(i);
             i--;
       }
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

16 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

InvalidOperationException: The list was modified. 1 Answer

A node in a childnode? 1 Answer

When removing something from a list it says missing 1 Answer

Removing object from a list also removes it from a different list? help! 2 Answers

build settings screen - how to delete old/unused scenes ? 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges