XNA Creators Club Online
Page 1 of 1 (7 items)
Sort Posts: Previous Next

Remove a list of indexes from list?

Last post 11/17/2009 3:07 PM by Kainsin. 6 replies.
  • 11/16/2009 3:50 PM

    Remove a list of indexes from list?

    This is probably something really simple but I haven't been able to find the answer. (one of those "too general of keywords makes searching neraly impossible" problems ;) )

    What I have is a list of indexes that I need to remove from a list. My problem is that once I start removing them, it changes the objects that the other indexes point at. For example:
    List<Object> objects =new List<Objects>();
    List<
    int> removalIndexes = new List<int>(); 
     
    for(int i=0;i<objects.Count;i++) 
        if(objects[i].MeetsRemovalConditions) 
        { 
            removalIndexes.Add(i); 
        } 
     
    foreach(int removeIndex in removalIndexes) 
        objects.RemoveAt(removeIndex); 

    Note that this is highly, highly simplified - the first loop is huge and other things are done to the objects inbetween the setting and actual removing so I can't remove the objects in the first loop like I normally would.

    Anyway, as you can imagine in the second loop, as soon as it starts iterating the indexes change. I'm guessing there's another, better way of doing this; possibly with a lambda expression? I tried searching for that but couldn't find a way to check based on its index in the list.

    I may just have to add a flag to the object itself to check if it needs to be removed, but I'd still like to know if there's a way to do this the way I originally intended, because I like cool C# tricks like this. ;D

    "Software is never finished, it is in varying states of 'less broken'" because "If it ain't broke, it doesn't have enough features yet"

    In Playtest: Avatar Land | The MANLY Game for MANLY Men

    The signature that was too big for the 512 char limit
  • 11/16/2009 4:01 PM In reply to

    Re: Remove a list of indexes from list?

    Loop through the list backwards...

    for (int i = objects.Count - 1; i >= 0; i--)  
      if (objects[i].MeetsRemovalConditions)  
        objects.Delete(i); 

  • 11/16/2009 4:20 PM In reply to

    Re: Remove a list of indexes from list?

    That won't work since I'm not looping through it again; if I were it would still change the indexes since they can be in any order... I suppose I could sort the removal indexes so they'll be largest to smallest and it would work. Odd that there isn't a more elegant solution built in to batch-remove objects via their indexes..
    "Software is never finished, it is in varying states of 'less broken'" because "If it ain't broke, it doesn't have enough features yet"

    In Playtest: Avatar Land | The MANLY Game for MANLY Men

    The signature that was too big for the 512 char limit
  • 11/16/2009 4:37 PM In reply to

    Re: Remove a list of indexes from list?


    I think you are stuck as all the lists and arrays I know of always have a continuous index.  You would need to look at creating your own class that has the unique function you need like Queue is a special first in first out list.

    Couple of other ideas:
    Can you set the element to null?
    Can you just mark the object as Inactive?  (Good for avoiding Xbox garbage collection.)


    **

    Well on the way to creating a 3D First person controls shooter with Over the Shoulder view... Another few YEARS and it'll be done!

    http://games.discoverthat.co.uk/ - Skinning Sample Dude for Blender and XNA Parallel Spilt Shadow Maps plus other stuff...

    My game development blog - Well a few notes from time to time...
  • 11/16/2009 5:02 PM In reply to

    Re: Remove a list of indexes from list?

    Answer
    Reply Quote
    UberGeekGames:
    That won't work since I'm not looping through it again; if I were it would still change the indexes since they can be in any order...


    In the example code you posted, a reverse loop would work fine, since the removal indices are always added in ascending order.

    If that's not always the case, and you can't rearrange things to guarantee stable index values, you will need to store object references instead of indices.
    XNA Framework Developer - blog - homepage
  • 11/17/2009 2:00 PM In reply to

    Re: Remove a list of indexes from list?

    Thanks Shawn. Here's a nice reuseable snippet in case anyone else needs the same functionality:
    //copy this into your program to use!
    public static class ListOperations 
        public static void RemoveIndexes<T>(this List<T> l, List<int> ranges) 
        { 
            ranges.Sort(); 
            ranges.Reverse(); 
     
            for (int i = 0; i < ranges.Count; i++) 
            { 
                l.RemoveAt(ranges[i]); 
            } 
        } 
     
    //example console app
    class Program 
        static void Main(string[] args) 
        { 
            List<string> ObjectList = new List<string>() { "0""1""2""3""4","5","6","7","8","9" }; 
            List<int> KillList = new List<int>() { 9, 3, 5, 7 }; 
     
            foreach (string s in ObjectList) 
                Console.WriteLine(s); 
                 
            Console.WriteLine("Removing indexes from list"); 
     
            ObjectList.RemoveIndexes(KillList); 
                 
            foreach (string s in ObjectList) 
                Console.WriteLine(s); 
     
            Console.ReadKey(); 
        } 

    Have I mentioned how much I love C# 3.0 lately? :D
    "Software is never finished, it is in varying states of 'less broken'" because "If it ain't broke, it doesn't have enough features yet"

    In Playtest: Avatar Land | The MANLY Game for MANLY Men

    The signature that was too big for the 512 char limit
  • 11/17/2009 3:07 PM In reply to

    Re: Remove a list of indexes from list?

    You can go one step further by using a comparison method instead of calling reverse.

    public static int ReverseIntComparison(int x, int y) {  
        return (y == x ? 0 : (y < x ? -1 : 1));  
    }  
     
    ...  
     
    ranges.Sort(ReverseIntComparison); 

    You could also make a static object that implements IComparer if garbage-collection is a problem with this.
    --Kainsin
Page 1 of 1 (7 items) Previous Next