--------------------------------------------------------------------
tA = {10,11, 20, 30, 40}
print(tA[1]) -- 10 이 찍힌다
print(tA[3]) -- 20 이 찍힌다
--------------------------------------------------------------------
--------------------------------------------------------------------
tB = {[0]=10,11, 20, 30, 40}
print(tB[1]) -- 11 이 찍힌다
print(tB[3]) -- 30 이 찍힌다
--------------------------------------------------------------------
--------------------------------------------------------------------
print(#tA) -- 5가 찍힌다
print(#tB) -- 4가 찍힌다
--------------------------------------------------------------------
--------------------------------------------------------------------
tA[4]=nil
print(tA[4]) -- nil 이 찍힌다
print(#tA) -- 여전히 5가 찍힌다.
--------------------------------------------------------------------
완전히 삭제하려면 table.remove()를 써야한다.
--------------------------------------------------------------------
table.remove(tA, 4)
print(tA[4]) -- 40이 찍힌다.
print(#tA) -- 이제 4가 찍힌다.
--------------------------------------------------------------------
--------------------------------------------------------------------
table.remove(tA, 4)
print(tA[4]) -- 40이 찍힌다.
print(#tA) -- 이제 4가 찍힌다.
--------------------------------------------------------------------
즉, table.remove()함수를 사용하면 그 즉시로 배열의 인덱스값이 달라진다. 원래 인덱스가 5였던 것이 4로 바뀌는 것이다. 이 사실은 반복문 안에서 table.remove()함수를 사용할 때 반드시 고려해야 한다.
프로그램을 작성하다보면 필요에 의해서 객체를 동적으로 생성한 후 (몬스터, 총알 등등) 배열에 집어넣게 된다. 그리고 어떤 조건에 맞으면 (화면에서 벗어났다던가) 그것을 삭제해야 되는데 그 조건 검사를 보통 for문으로 다음과 같이 하게 된다.
--------------------------------------------------------------------
for id=1, #tA do
...
프로그램을 작성하다보면 필요에 의해서 객체를 동적으로 생성한 후 (몬스터, 총알 등등) 배열에 집어넣게 된다. 그리고 어떤 조건에 맞으면 (화면에서 벗어났다던가) 그것을 삭제해야 되는데 그 조건 검사를 보통 for문으로 다음과 같이 하게 된다.
--------------------------------------------------------------------
for id=1, #tA do
...
if condition1 == true then
...
tA[id]:revmoveSelf()
tA[id]:revmoveSelf()
tA[id] = nil
end
...
...
end
--------------------------------------------------------------------
그냥 이렇게 하는 걸로는 충분하지 않은 이유는 배열의 크기는 그대로이기 때문에 새로운 객체가 생성될 때마다 배열이 계속 커지게 된다. 시간이 지날수록 조건 검사의 부담이 늘어날 것이다. 그래서 table.remove()를 다음과 같이 써야 한다.
--------------------------------------------------------------------
for id=1, #tA do
...
--------------------------------------------------------------------
--------------------------------------------------------------------
for id=1, #tA do
...
if condition1 == true then
...
tA[id]:removeSelf()
table.remove(tA, id)
end
...
end
--------------------------------------------------------------------
그런데 이렇게 하면 모든 요소에 대해서 제대로 검사가 수행이 되지 않는데 그 이유는 table.remove()함수가 실행되면 그 즉시로 인덱스가 변하기 때문에 하나를 건너뛰게 되기 때문이다. 예를 들어 4번 요소가 조건이 맞아서 삭제되면 원래 5번이었던 것이 4번이 되고 그 다음 반복에서는 5번이(원래는 6번 이었던 것) 검사가 되기 때문이다.
간단한 해법은 역순으로 검사를 하는 것이다.
--------------------------------------------------------------------
for id=#tA, 1, -1 do
...
--------------------------------------------------------------------
간단한 해법은 역순으로 검사를 하는 것이다.
--------------------------------------------------------------------
for id=#tA, 1, -1 do
...
if condition1 == true then
...
tA[id]:removeSelf()
table.remove(tA, id)
end
...
end
--------------------------------------------------------------------
이렇게 하면 table.remove()가 실행되어도 이후에 검색할 요소의 인덱스는 변하지 않으므로 모든 배열 요소에 대해서 조건검사가 수행이 되게 된다.
--------------------------------------------------------------------
댓글 없음:
댓글 쓰기