Is there a good way to do this?
-
Say I've got some type of collection (usually an ArrayList), and I need to itterate through it, call some methods, and possibly remove one or more of the elements. You cant modify a collection while enumerating through it. If its an Array I could access it with an index variable, but then I need to always check if the size has changed and adjust for that (which is incredibly tricky because you dont know which element was removed and whether you need to readjust your index value or not). Are there any elegant ways of doing this? Heres what I mean
for(int i=0; i < m_objects.Count; i++) { PhysicsObject obj2 = (PhysicsObject)m_objects[i]; if(obj2 == obj) continue; if(rect.IntersectsWith(obj2.getBoundingBox()) || rect.Contains(obj2.getBoundingBox())) { //collision obj.onCollision(obj2); //This could remove an object from m_objects obj2.onCollision(obj); //This could remove an object from m_objects } //If an object was removed m_objects.Count is one less. If the object that was removed had //already been enumerated, we need to do the same index again (all elements shift down) //if it hasnt been enumerated, we dont do anything to i. }
This may be more a design problem. I can think of a few ways to hack around this (dont delete objects inside of onCollision, just put them in a queue to be deleted after all collision detections are done), but Im hoping theres an elegant way to itterate through a collection and be able to remove elements without stepping on your toes. Thanks for any help Dave Ratti -
Say I've got some type of collection (usually an ArrayList), and I need to itterate through it, call some methods, and possibly remove one or more of the elements. You cant modify a collection while enumerating through it. If its an Array I could access it with an index variable, but then I need to always check if the size has changed and adjust for that (which is incredibly tricky because you dont know which element was removed and whether you need to readjust your index value or not). Are there any elegant ways of doing this? Heres what I mean
for(int i=0; i < m_objects.Count; i++) { PhysicsObject obj2 = (PhysicsObject)m_objects[i]; if(obj2 == obj) continue; if(rect.IntersectsWith(obj2.getBoundingBox()) || rect.Contains(obj2.getBoundingBox())) { //collision obj.onCollision(obj2); //This could remove an object from m_objects obj2.onCollision(obj); //This could remove an object from m_objects } //If an object was removed m_objects.Count is one less. If the object that was removed had //already been enumerated, we need to do the same index again (all elements shift down) //if it hasnt been enumerated, we dont do anything to i. }
This may be more a design problem. I can think of a few ways to hack around this (dont delete objects inside of onCollision, just put them in a queue to be deleted after all collision detections are done), but Im hoping theres an elegant way to itterate through a collection and be able to remove elements without stepping on your toes. Thanks for any help Dave RattiYou could have the OnCollision method return a bool indicating if the method has removed an object who`s index is smaller or equal to i and then do i--; if(obj.onCollision(obj2) || obj2.onCollision(obj)) { i--; }
-
Say I've got some type of collection (usually an ArrayList), and I need to itterate through it, call some methods, and possibly remove one or more of the elements. You cant modify a collection while enumerating through it. If its an Array I could access it with an index variable, but then I need to always check if the size has changed and adjust for that (which is incredibly tricky because you dont know which element was removed and whether you need to readjust your index value or not). Are there any elegant ways of doing this? Heres what I mean
for(int i=0; i < m_objects.Count; i++) { PhysicsObject obj2 = (PhysicsObject)m_objects[i]; if(obj2 == obj) continue; if(rect.IntersectsWith(obj2.getBoundingBox()) || rect.Contains(obj2.getBoundingBox())) { //collision obj.onCollision(obj2); //This could remove an object from m_objects obj2.onCollision(obj); //This could remove an object from m_objects } //If an object was removed m_objects.Count is one less. If the object that was removed had //already been enumerated, we need to do the same index again (all elements shift down) //if it hasnt been enumerated, we dont do anything to i. }
This may be more a design problem. I can think of a few ways to hack around this (dont delete objects inside of onCollision, just put them in a queue to be deleted after all collision detections are done), but Im hoping theres an elegant way to itterate through a collection and be able to remove elements without stepping on your toes. Thanks for any help Dave RattiLook into an "Iterator" design pattern. I'm not sure...there might even be an interface for it in the .NET framework.
There are only 10 types of people in this world....those that understand binary, and those that do not.