[C#] List Remove 에러
C#의 List클래스
C#
에서 지원하는 콜렉션으로 내부 자료형으로 클래스를 넣을 수 있어서 활용도가 매우 높다..!
또한, 정적 배열이 아닌 동적으로 배열의 크기를 조절할 수 있고 많은 기능을 포함하고 있다.
인덱스로 액세스할 수 있는 강력한 형식의 개체 목록을 나타냅니다. 목록의 검색, 정렬 및 조작에 사용할 수 있는 메서드를 제공합니다.
list 요소 삭제
using System.Collections.Generic;
using UnityEngine;
public class ListRemove : MonoBehaviour
{
private List<int> myList = null;
void Start()
{
myList = new List<int>();
myList.Add(1);
myList.Add(2);
myList.Add(3);
myList.Add(4);
foreach (var param in myList)
{
print(param);
}
}
}
위 처럼 간단한 c# list코드가 있다고 한다면 코드는 문제없이 돌아간다.
1 2 3 4 출력
public class ListRemove : MonoBehaviour
{
private List<int> myList = null;
void Start()
{
myList = new List<int>();
myList.Add(1);
myList.Add(2);
myList.Add(3);
myList.Add(4);
foreach (var param in myList)
{
print(param);
}
for (int i = 0; i < myList.Count; i++)
{
print(myList[i]);
myList.RemoveAt(i);
}
foreach (var param in myList)
{
print(param);
}
}
}
이 코드도 일단 문제없이 돌아간다.
보기에는 문제가 없어보이지만 실제로 작동방식을 보면 큰 문제를 초래할 수 있다.
저 코드에서 출력값은
- 첫 번째 foreach문은 1 2 3 4
- 두 번째 for문은 1 3
- 세 번째 for문은 2 4
버그아니야..? 라고 생각할 수 있지만 list의 특성과 코드를 자세히 다시 본다면 정상적인 코드이다.
처음 list.add당시 배열에는 1, 2, 3, 4가 들어간다.
두 번째 for문의 경우 반복 조건은 myList.Count이므로 총 4번의 반복을 해야한다. 증감은 +1씩 이루어진다.
list는 요소를 삭제하는 경우 인덱스를 앞으로 하나씩 밀기 때문에 빈 공간이 존재하지 않는다.
따라서 처음 1을 삭제하고 나머지 2, 3, 4의 인덱스가 하나씩 밀리고 list의 크기가 1 줄어든다.
{2, 3, 4} 크기 3 i는 1
다음 반복문에서 삭제되는 값은 3으로 배열의 크기만큼 순회하게 된다.
{2, 4} 크기는 2 i는 2
반복 종료..
실제로 list에 남아있는 값은 2, 4가 남아 있지만 반복은 정상적으로 종료된 상태이다.
이러한 list의 요소를 순회 삭제하고 싶다면 어떤 방식으로 접근해야 할까..?
역 순회
for (int i = myList.Count - 1; i >= 0; i--)
{
print(myList[i]);
myList.RemoveAt(i);
}
처음부터 배열의 마지막부터 삭제를 한다면 인덱스의 당김 없이 원할하게 삭제가 가능하다.
인덱스 0으로 순회
정리하다가 테스트해본 방법인데 위험성은 있지만 재밌는 것 같아서..?
for (int i = 0; i < myList.Count; )
{
print(myList[i]);
myList.RemoveAt(i);
}
위 방법도 정상적으로 삭제는 되지만 2가지 큰 문제점이 있다.
- 리스트의 크기가 매우 큰 경우 아마도 삭제할 때 마다 인덱스의 당김 작업이 있을 텐데 배열의 크기만큼 시간이 든다.
- 만약 삭제에 대한 조건이 있을 경우 증감이 없기 때문에 조건이 맞지 않는다면 무한루프에 빠지게 될 수 있다..!
정리하자면 list의 삭제의 경우에는 역반복을 사용하여 요소를 삭제해야 한다..!
댓글남기기