Search Unity

Confirming an element exists in a list of class

Discussion in 'Getting Started' started by KillianQ, Mar 18, 2019.

  1. KillianQ

    KillianQ

    Joined:
    Apr 25, 2018
    Posts:
    1
    I want to check through a list, and if the element fulfills some requirement and, of course, exists, then remove it from the list. This has not been a problem for me in the past by simply utilising ElementAt(i), like so:

    Code (CSharp):
    1.         int eventCount = events.Count;
    2.         for (int i = 0; i < eventCount; i++)
    3.         {
    4.             if (events.ElementAtOrDefault(i))
    5.             {
    6.                 if (events[i] == effect)
    7.                 {
    8.                     events.Remove(events[i]);
    9.                 }
    10.             }
    11.         }
    However, when I change my List to contain a class instead of a single item:
    Code (CSharp):
    1.     private class TurnByTurnEvent
    2.     {
    3.         public int TurnsToExecute;
    4.         public int CurrentTurn;
    5.         public SkillEffects Effect;
    6.         public Callback Method;
    7.         public UnitControl Unit;
    8.         public GameObject EffectObject;
    9.     }
    10.  
    11.     private List<TurnByTurnEvent> events;
    Then ElementAt no longer operates in the same way. I have tried a few different approaches, but unfortunately seem to be getting further from the solution.
    Code (CSharp):
    1.         int eventCount = events.Count;
    2.         for (int i = 0; i < eventCount; i++)
    3.         {
    4.             if (events.ElementAt(i))
    5.             {
    6.                 var turnByTurnEvent = events[i];
    7.                 if (turnByTurnEvent.Effect == effect)
    8.                 {
    9.                     events.Remove(turnByTurnEvent);
    10.                 }
    11.             }
    12.         }
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    You should iterate backwards, not forwards, when deleting things from a list; otherwise if there are two matches in a row, you will miss the second of these. (Work through an example step by step to see why.)

    Also, when you already have the index, then use RemoveAt rather than Remove. Remove forces C# to search through the list (again) to find the element you've told it to remove. Or when you really do want to remove an element by element, then you can skip the loop entirely and have Remove do the searching for you.

    But in your second example, you're looking for an element where .Effect == effect. This will be true only when these two object references are the exact same object, or you have overridden the appropriate comparison operators in your SkillEffects class, and whatever code that runs has determined that the two objects are equal. I suspect you haven't done any operator overriding — it's a fairly advanced topic — and I suspect also that the two effects in question, even if you consider them to be "equal," are not the same object. Therefore == evaluates to false.