简体   繁体   中英

Clearing a list using a for loop

I'm making a Black Jack game, and at the start of every new round I need to clear the list of cards that represents the Player's and the Dealer's hands. I used this to do so:

public void ClearPlayerHand()
        {
            for (int i = 0; i < PlayerHand.Count; ++i) 
            {
                PlayerHand.Remove(PlayerHand[i]);
            }
        }

Problem is I always seem to be left with one card left in the list, or I receive an out of bounds error, no matter how I change the value of i, what is the best method of removing all the elements from the PlayerHand?

If your collection PlayerHand implements ICollection<T> you can just call the .Clear() method.

A common implementation of this interface is List<T> .

If you do want to clear a List<T> via a for loop, you should use a reverse for loop. The reason for this is that as you remove an item from the list, it will shift all the index's down one, and you could easy run into index out of bounds exceptions.

An example of this would be:

        for (int i = PlayerHand.Count - 1; i >= 0; i--)
        {
            PlayerHand.RemoveAt(i);
        }

The other answers are right: use Clear .

But, if you wanted to do this with a loop and Remove calls, here's how you would do it:

for(int i = PlayerHand.Count - 1; i >= 0; i--)
{
  PlayerHand.RemoveAt(i);
}

Reversing the direction of the iteration is the real trick.

This is the best/easiest way to do it.

PlayerHand.Clear();

Reason for out of bounds

As for why you are receiving the out of bounds exception, it's happening because you're removing elements from the list but continually counting up. You would want the last operation to remove i = 0 but it keeps counting.

Say PlayerHand has 3 items in it, the following occurs:

i = 0
remove PlayerHand[0] (it now contains 2 elements)
i = 1
remove PlayerHand[1] (it now contains 1 element)
i = 2
remove PlayerHand[2] (this throws an exception as only PlayerHand[0] exists)

Normally you would count backwards in this case:

for (int i = PlayerHand.Count - 1; i >= 0; i--) 

Another suggested approach beside Clear method, you can also use RemoveAll to either remove all or part of list

// Remove all items
PlayerHand.RemoveAll(x => true);

// Remove part of list
PlayerHand.RemoveAll(x => ConditionMethod(x));

Alternatively, you can consider using data binding and then you should update the ItemSource, instead of directly manipulating the listbox or listview items.

List<T> SomeSource=...
PlayHand.ItemSource=SomeSource;
SomeSource.Clear();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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