📝 Array.prototype.splice 명세
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
매개변수
1. start
배열 변경을 시작할 인덱스
- 정수 문자열은 정수로 변환
- 정수, 정수 문자열 외 다른 입력은 모두 0으로 간주
- 음의 정수(-n)는 배열의 마지막 요소부터 n번째 인덱스(array.length - n)로 변환
2. deleteCount
배열에서 제거할 요소의 수
- 자연수 문자열은 정수로 변환
- 자연수, 자연수 문자열 외 다른 입력은 모두 0으로 간주
3. item1, item2, ...
배열에 추가할 요소
반환값
제거한 요소를 담은 배열
기타
- Array.prototoype.splice는 원본 배열의 요소를 변경시킨다.
💻️ 구현
const mySplice = function (start, deleteCount, ...items) {
const deletedArray = [];
const startIndex = Number.isInteger(Number(start))
? start < 0
? this.length + Number(start)
: Number(start)
: 0;
const count = (Number.isInteger(Number(deleteCount)) && deleteCount > 0)
? Number(deleteCount)
: 0;
const endIndex = Math.min(startIndex + count, this.length);
if (count) {
for (let i = startIndex; i < endIndex; i++) {
deletedArray[i - startIndex] = this[i];
}
for (let i = startIndex; i < this.length; i++) {
this[i] = this[i + count];
}
this.length -= endIndex - startIndex;
}
if (items.length) {
for (let i = this.length - 1; i >= startIndex; i--) {
this[i + items.length] = this[i];
}
for (let i = 0; i < items.length; i++) {
this[startIndex + i] = items[i];
}
}
return deletedArray;
};
Array.prototype.mySplice = mySplice;
명세에 맞게 매개변수로 들어온 값을 정수 또는 자연수로 변환한다.
endIndex는 삭제할 원소를 순회할 때 사용하므로, 원본 배열의 길이보다 길 수 없다.
deleteCount로 자연수(또는 자연수 문자열)가 전달되었다면,
deletedArray에 삭제된 요소를 저장하고 삭제된 요소의 자리에 뒤에 있는 요소들을 순서에 맞게 할당한다.
마지막으로 배열의 길이를 삭제된 개수에 맞게 재설정한다.
items로 1개 이상의 요소가 전달되었다면,
startIndex번째 요소부터 마지막 요소까지 item의 개수만큼 뒤에 있는 index에 할당한다.
그 다음 startIndex부터 item의 개수만큼 차례로 item의 요소로 교체한다.
push나 pop을 사용하지 않고 인덱스와 length만으로 구현하기 위해 위와 같은 방식으로 작성하였다.
🧪 테스트 (Jest)
test('Array.prototype.splice 테스트', () => {
const starts = [undefined, -3, -2, -1, 0, 1, 2, 3, 4, 5, '-1', '0', '1', 'foo'];
const deleteCounts = [undefined, -1, 0, 1, 2, 3, 4, 5, 6, '-1', '0', '1', 'foo'];
const itemLists = [[], [0], [6, 7, 8, 9, 10], [false, undefined, 'foo', [], {}]];
starts.forEach(start => {
deleteCounts.forEach(deleteCount => {
itemLists.forEach(items => {
const arr1 = [1, 2, 3, 4, 5];
const arr2 = [1, 2, 3, 4, 5];
expect(arr1.mySplice(start, deleteCount, ...items))
.toEqual(arr2.splice(start, deleteCount, ...items));
expect(arr1).toEqual(arr2);
});
});
});
});
매개변수 start와 deleteCount에 대해 인자로 전달되지 않았을 때(undefined), 음의 정수 / 0 / 자연수일 때, 정수 문자열일 때, 일반 문자열일 때 등의 경우에 대해서 그 모든 결과가 Array.prototype.splice의 결과와 일치하는지 확인한다.
item의 경우 item이 전달되지 않았을 때([]), 1개 또는 여러 개 전달될 때, 여러 타입들이 전달될 때를 확인하였다.
참고자료
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
'연습장 > 낙서장' 카테고리의 다른 글
[React/TS] 이벤트 핸들러 함수의 타입 (0) | 2022.11.27 |
---|---|
[JavaScript] Array.prototype.map 직접 구현하기 (0) | 2022.04.06 |