
오늘은 자바스크립트의 하위 배열을 다루는 slice()와 splice() 배열 메서드와 더불어 이름이 비슷한 split() 메서드까지 다뤄보려한다. 이름은 비슷하지만 세 메서드 모두 서로 너무 다른 메서드이므로 꼼꼼히 비교 정리 해보자.
slice() 메서드는 어떤 배열 또는 문자열을 start 인덱스부터 end 인덱스까지 선택하여 새로운 배열 혹은 문자열로 반환한다. 이 메서드는 얕은 복사본을 반환하므로 원본 배열은 바뀌지 않지만 반환 요소가 원시 타입이 아닌 참조 타입일 경우, 반환값 수정 시 원본에 영향이 가거나 원본이 수정될 시 복사본의 해당 요소에 영향을 받을 수 있다.
slice() 메서드의 기본 문법은 다음과 같다.
array.slice(start, end);
string.slice(start, end);
이렇듯 이 메서드는 순서대로 시작 인덱스(필수 인자)와 종료 인덱스(선택 사항 인자) 를 받는다.
기억해야할 점은 실질적으로 잘리는 부분은 (종료 인덱스 - 1) 이라는 것이다.
start: 잘라내기 시작할 인덱스Number(포함)
end: 잘라내기 종료할 인덱스Number(미포함)
start와 end 인자 모두 숫자형이어야 한다. 하지만 만약 문자열이 온다면 "2","10" 처럼 숫자로 변환할 수 있을 때에는 숫자형으로 변환되고, 변환할 수 없을 경우 NaN으로 처리되어 기본값으로 간주된다..(0 또는 배열 길이)
만약 부동소수점 숫자가 온다면 소수점을 무시하고 정수로 변환되어 작동하며, 음수가 올 경우 역방향 인덱스를 사용하게 된다.
// 배열 예제
const numbers = [1, 2, 3, 4, 5];
const slicedNumbers = numbers.slice(1, 4);
console.log(slicedNumbers); // [2, 3, 4] (numbers[4]=5이지만, 두 번째 요소부터 네 번째 요소까지 나옴)
console.log(numbers); // [1, 2, 3, 4, 5] (원본 배열은 변경되지 않음)
// 문자열 예제
const text = "Hello, World!";
const slicedText = text.slice(0, 5);
console.log(slicedText); // "Hello"
console.log(text); // "Hello, World!" (원본 문자열은 변경되지 않음)
음수가 올 경우 역방향 인덱스로 작동하는 예시 코드
const arr = [10, 20, 30, 40, 50];
console.log(arr.slice(-3, -1)); // [30, 40]
// start: 길이 - 3 (2번째 요소), end: 길이 - 1 (마지막 요소 이전)
splice() 메서드는 배열의 기존 요소를 삭제 또는 교체하거나 새 요소를 추가하여 배열의 내용을 변경한다. 즉 원본 배열을 직접 수정하는 파괴적 메서드이다.
이 메서드의 반환값 은 제거한 요소를 담은 배열 [] 이다. 하나의 요소만 제거한 경우 길이가 1인 배열을 반환한다. 아무 값도 제거하지 않았으면 빈 배열을 반환한다.
splice() 메서드의 기본 문법은 다음과 같다.
array.splice(start, deleteCount, ...items);
이렇듯 순서대로
start: 변경을 시작할 인덱스Number
deleteCount: 제거할 요소의 개수Number
items: 제거된 위치에 추가할 요소(선택 사항)
인자를 받는다. slice() 메서드와 달리 원본 배열을 수정하는 이 메서드는, 기존 요소에 교체, 삭제, 추가 등의 다양한 작업을 수행할 수 있기 때문에 각 예제로 나누어 잘 살펴보자.
splice() 로 원본 배열의 요소를 제거하고 반환값으로 제거된 요소를 받는 코드이다.
const fruits = ["Apple", "Banana", "Cherry", "Date"];
const removed = fruits.splice(1, 2);
console.log(fruits); // ["Apple", "Date"] (원본 배열 변경)
console.log(removed); // ["Banana", "Cherry"] (제거된 요소 반환)
splice() 로 추가할 요소를 ...items로 전달하여 원본 배열에 요소를 삽입할 수 있다.
const numbers = [1, 4, 5];
numbers.splice(1, 0, 2, 3); // 1번 인덱스에 아무 것도 제거하지 않고 [2,3]을 삽입
console.log(numbers); // [1, 2, 3, 4, 5]
splice() 로 deleteCount를 지정하고 ...items로 새로운 요소를 전달하여 기존 요소를 교체할 수 있다.
const letters = ["A", "B", "C"];
letters.splice(1, 1, "X", "Y");
console.log(letters); // ["A", "X", "Y", "C"]
split() 메서드는 문자열을 지정된 구분자(Separator) 를 기준으로 나누어 배열 로 반환하는 메서드이다. 이 메서드는 문자열 메서드이지만 반환값이 배열이고 앞선 메서드들과 이름도 비슷하여 그냥 이 포스팅에서 함께 다룬다.
이 메서드는 비파괴적 메서드로, 원본 문자열을 변경하지 않고 새로운 배열을 생성하여 반환한다. 원본 문자열을 구분자로 나누어 새로운 배열로 반환하는 메서드이기 때문에 당연히 이 반환값은 원본 문자열과 완전히 독립적인 새로운 배열이며, 원본 문자열에는 영향을 미치지 않는다.
이 메서드는 정규표현식, 배열 메서드와의 조합 등을 활용해 강력한 문자열 처리가 가능한 메서드이기 때문에 실무에서 문자열을 다루는 작업의 기본 도구로 자주 사용된다고 한다. 이 포스팅을 작성하게 된 것도 이 메서드를 제대로 공부해놓기 위함이며 이 메서드의 필요성을 느낀 계기는 우테코 프리코스 1주차 과제인 문자열 덧셈기를 만들면서이다.
string.split(separator, limit);
이 메서드는 문자열을 나눌 기준인 구분자 를 첫 번째 인자로 받고 나눌 요소의 최대 개수를 두 번째 인자로 받는다.
실질적으로 split() 메서드의 강력한 기능은 이 구분자에 문자열 뿐만 아니라 정규표현식이 올 수 있다는 것인데, 우테코 프리코스 1주차 과제의 첫 난관이 이 부분이었다. 커스텀 구분자를 만들기 위해 구분자를 동적으로 정의해야했기 때문이다. 해당 고난은 이 블로그의 우테코 1주차 회고에서 자세히 확인할 수 있다.
아무튼, split() 메서드를 더 잘 활용하기 위해서는 정규 표현식과 RegExp 클래스를 함께 학습하면 좋을 것이다.
separator(선택 사항 인자) : 문자열을 나눌 기준이 되는 구분자이다.문자열또는정규표현식이 될 수 있으며, separator를 생략하면 문자열 전체가 하나의 요소로 포함된 배열을 반환한다.
limit(선택 사항 인자) : 나눌 요소의 최대 개수를 지정한다. 나눌 수 있는 개수에 도달하면 그 이후의 문자열은 무시된다.
,를 구분자로 문자열을 나눠 배열로 저장하기
const text = "Apple, Banana, Cherry";
const fruits = text.split(", ");
console.log(fruits); // ["Apple", "Banana", "Cherry"]
정규표현식을 사용해 모든 숫자[0-9]를 기준으로 구분하게 하기
* 정규표현식은 /와 / 사이에 패턴을 작성. \d 는 아스키 숫자 전체에 일치하는 정규 표현식 문자 클래스.
const text = "a1b2c3d4";
const result = text.split(/\d/);
console.log(result); // ["a", "b", "c", "d", ""]
RegExp 생성자를 사용하여 구분자를 "#", "|", ";" 로 갖도록 동적으로 구분자 만들어보기
// 문자열에서 사용자 정의 구분자를 이용해 나누기
const text = "apple#banana|cherry;date";
// 동적으로 구분자를 생성
const customDelimiter = "[#|;]";
const regex = new RegExp(customDelimiter, "g");
// RegExp 생성자를 사용한 split
const result = text.split(regex);
console.log(result); // ["apple", "banana", "cherry", "date"]
RegExp 생성자를 사용하여 구분자를 "#|;" 로 갖도록 동적으로 구분자 만들어보기 ("!@#"를 세트로 입력해야만 되게)
const text = "apple!@#banana!@#cherry";
// 동적으로 정규표현식 생성
const customDelimiter = "!@#";
const regex = new RegExp(customDelimiter, "g");
// split 사용
const result = text.split(regex);
console.log(result); // ["apple", "banana", "cherry"]
| 메서드 | 대상 | 반환값 | 원본 수정 여부 | 주요 기능 |
|---|---|---|---|---|
slice() | 배열/문자열 | 선택한 부분의 새로운 배열/문자열 | 변경하지 않음 | 특정 범위의 요소를 선택하여 새로운 배열/문자열 생성 |
splice() | 배열 | 제거된 요소를 담은 배열 | 변경함 | 요소를 추가, 제거, 또는 교체하여 원본 배열 수정 |
split() | 문자열 | 나눈 문자열을 담은 배열 | 변경하지 않음 | 구분자를 기준으로 문자열을 나누어 배열로 반환 |
slice() 는 특정 범위를 복사하여 반환하므로 원본 데이터가 수정되지 않음.splice() 는 원본 배열을 직접 수정하며, 반환값은 제거된 요소로 구성된 배열임.split() 은 문자열만 대상으로 하며, 구분자를 기준으로 문자열을 나누어 배열로 반환함.글 작성 참고 사이트:
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/split
글 작성 참고 서적: 자바스크립트 완벽 가이드 - 데이비드 플래너건 저자
https://product.kyobobook.co.kr/detail/S000001033131