JavaScript로 개발하다 보면 다음과 같이 중간중간 빈(empty) 요소가 섞여 있는 배열을 마주치는 경우가 있습니다.
const arr = [4, 6, , 45, 3, 345, , 56, 6];
배열 리터럴에서 쉼표 사이에 값이 생략되면 해당 자리는 undefined가 됩니다. 이번 글에서는 이런 배열에서 undefined 요소만 골라내 제거하는 방법을 알아보겠습니다.
핵심 포인트: falsy 값이 아닌 undefined만 제거한다
주의할 점은 false, 0, ''(빈 문자열), null 같은 falsy 값까지 모두 지우는 것이 아니라, 오직 undefined와 빈 슬롯(hole)만 제거해야 한다는 것입니다. 따라서 단순히 truthy/falsy 여부로 필터링하면 안 되고, 각 요소의 타입을 직접 확인해야 합니다.
구현 방법: for 루프와 Array.prototype.splice()
가장 직관적인 방법은 for 루프로 배열을 순회하면서 Array.prototype.splice()를 사용해 undefined 요소를 제자리(in-place)에서 삭제하는 것입니다.
예제 코드
const arr = [4, 6, , 45, 3, 345, , 56, 6]
const eliminateUndefined = arr => {
for(let i = 0; i < arr.length; ){
if(typeof arr[i] !== 'undefined'){
i++;
continue;
};
arr.splice(i, 1);
};
};
eliminateUndefined(arr);
console.log(arr);코드 동작 원리
- 인덱스 증가 조건 분리: 일반적인
i++를 반복문 선언부에 넣지 않고, 현재 요소가 정상적인 값일 때만 인덱스를 증가시킵니다. - undefined 감지:
typeof arr[i] !== 'undefined'조건으로 값이 존재하는 경우에만 다음 요소로 넘어갑니다. - 제자리 삭제: undefined를 만나면
arr.splice(i, 1)로 해당 위치의 요소 하나를 삭제합니다. 이때 인덱스를 증가시키지 않는 이유는, 삭제 후 그 자리에 새로운 요소가 들어왔기 때문입니다.
실행 결과
위 코드를 실행하면 콘솔에 다음과 같이 출력됩니다.
[ 4, 6, 45, 3, 345, 56, 6 ]
보시다시피 두 개의 빈 슬롯이 깔끔하게 제거되고, 나머지 유효한 숫자들은 모두 그대로 유지됩니다.
마무리 및 참고 사항
이 방식은 원본 배열을 직접 수정하기 때문에 별도의 새 배열을 만들 필요가 없다는 장점이 있습니다. 만약 원본을 유지하고 싶다면 filter() 메서드를 활용해 arr.filter(el => el !== undefined)처럼 새 배열을 반환받는 방법도 고려할 수 있습니다. 상황에 맞게 제자리 수정과 불변성(immutability) 방식 중 선택하시면 됩니다.