본문 바로가기
Javascript 데이터 구조 & 알고리즘 공부

배열이나 문자열 자르는 메소드: slice, substring, splice 정리

by cuziam 2023. 5. 18.

 

공부하다가 배열이나 문자열 자르는 메소드들이 헷갈려서 예시코드와 함께 정리했다. slice, substring, splice 얘네들은 하는 일은 뭔가를 자른다는 점에서 비슷하다. 근데 조금 하는 일이 다르다. 모질라 재단의 공식문서를 참고해서 해당 내용들을 공부하고 정리했다.

 

*String.prototype.substr()함수 같은 경우 ECMAScript 표준에서 Deprecated (사용 권장 X)으로 나타나있습니다. 이것 대신 slice나 substring을 사용하는 것이 권장되므로 이 글에서 substr() 함수는 정리하지 않았습니다.

 

Array.prototype.slice()

slice() 메서드는 어떤 배열의 begin부터 end까지(end 미포함)에 대한 얕은 복사본을 새로운 배열 객체로 반환합니다. 원본 배열은 바뀌지 않습니다.
출처: MDN web docs: Array.protype.slice()
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];

console.log(animals.slice(2));
// Expected output: Array ["camel", "duck", "elephant"]
// start 매개변수만 있는 경우, 해당 인덱스부터 끝까지를 잘라서 반환한다.

console.log(animals.slice(2, 4));
// Expected output: Array ["camel", "duck"]

console.log(animals.slice(1, 5));
// Expected output: Array ["bison", "camel", "duck", "elephant"]

console.log(animals.slice(-2));
// Expected output: Array ["duck", "elephant"]
// 음수 인수는 배열 끝에서 부터의 길이를 의미한다.

console.log(animals.slice(2, -1));
// Expected output: Array ["camel", "duck"]
// 양수 인수와 음수 인수를 같이 사용할 수 있다.

console.log(animals.slice());
// Expected output: Array ["ant", "bison", "camel", "duck", "elephant"]
// 매개변수가 없다면 본래 배열을 복사만 해서 반환한다.
  • 구문: arr.slice([begin[, end]])
  • 매개변수:
    • begin(optional): 추출 시작점에 대한 인덱스.
    • end(optional): 추출을 종료할 기준 인덱스.
  • 반환값: 추출한 요소를 포함한 새로운 배열.
  • 하는 일: 배열의 begin 인덱스 부터 end 이전 인덱스(end-1)까지 배열을 잘라서, 얕은 복사해서 반환한다.
  • 동작특징
    • 배열을 복사해서 반환한다.
    • 매개변수가 둘 다 없으면 원래의 배열을 얕은 복사해서 내놓는다.
    • 음수 인수를 사용할 수 있다.
    • 문자열 객체(String)에도 거의 동일한 작업을 수행하는 메소드(String.prototype.slice())가 존재한다. 하지만 문자열은 불변하므로(immutable) 얕은 복사를 하는 것이 아니라, 문자열 객체를 새로 만들어서 사용한다. 이 점만 빼면 메소드의 사용법은 배열과 동일하다.
//String.prototype.slice()의 경우 문자 객체를 따로 만드는 방식을 사용한다.
let originalString = "Hello, world!";
let copiedString = originalString.slice(); // 별개의 문자열을 반환하는 것으로 취급됨.

originalString = "Modified";

console.log(copiedString); // "Hello, world!"

//한편 String.prototype.slice()의 경우 얕은 복사를 수행한다.
let originalArray = [1, 2, 3];
let shallowCopy = originalArray.slice(); // 얕은 복사 발생

originalArray[0] = 10;

console.log(shallowCopy); // [10, 2, 3]

String.prototype.substring()

메소드는 string 객체의 시작 인덱스로 부터 종료 인덱스 전 까지 문자열의 부분 문자열을 반환합니다.
출처: MDN web docs: String.prototype.substring()
var anyString = 'Mozilla';

// Displays 'M'
console.log(anyString.substring(0, 1));
console.log(anyString.substring(1, 0));

// Displays 'Mozill'
console.log(anyString.substring(0, 6));

// Displays 'lla'
console.log(anyString.substring(4));
console.log(anyString.substring(4, 7));
console.log(anyString.substring(7, 4));

// Displays 'Mozilla'
console.log(anyString.substring(0, 7));
console.log(anyString.substring(0, 10));
  • 구문: str.substring(indexStart[, indexEnd])
  • 매개변수:
    • indexStart(optional): 추출 시작점에 대한 인덱스.
    • indexEnd(optional): 추출을 종료 할 기준 인덱스이다.
  • 반환값: 기존문자열의 부분 문자열 반환.
  • 하는 일: 배열의 indexStart인덱스 부터 indexEnd 이전(end-1)까지의 부분 문자열을 새로 만들어서 반환한다.
  • 동작특징
    • 문자열에만 있는 메소드이다.(배열에는 substring이 없다. 말 그대로 sub+string이니까)
    • String.prototype.slice()와 거의 동일한 작업을 수행한다. 하지만 아래의 두 가지 점에서 차이점이 있다.
      1. 음수 인수 처리: slice는 양수와 음수 둘 다 사용 가능하지만, 반면 substring는 양수 인수만 사용한다.
        0보다 작은 인수는 0으로 처리한다.
      2. 인자 처리 방식: slice는 첫 번째 인자가 더 크면, 빈 문자열을 반환하지만. 반면 substring은 첫 번째 인자와 두번째 인자를 바꾸어서 처리한다.
let str = "Hello, world!";

console.log(str.substring(0, 5)); // "Hello"
console.log(str.substring(7, 12)); // "world"
console.log(str.substring(12, 7)); // "world" (인덱스가 바뀌어도 처리)
console.log(str.substring(-5)); // "Hello, world!" (음수 인덱스 처리)

console.log(str.slice(0, 5)); // "Hello"
console.log(str.slice(7, 12)); // "world"
console.log(str.slice(12, 7)); // "" (빈 문자열)
console.log(str.slice(-5)); // "rld!" (음수 인덱스 처리)

Array.prototype.splice()

splice() 메서드는 배열의 기존 요소를 삭제 또는 교체하거나 새 요소를 추가하여 배열의 내용을 변경합니다.
출처: MDN web docs: Array.prototype.splice()
const months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb');
// Inserts at index 1
console.log(months);
// Expected output: Array ["Jan", "Feb", "March", "April", "June"]

months.splice(4, 1, 'May');
// Replaces 1 element at index 4
console.log(months);
// Expected output: Array ["Jan", "Feb", "March", "April", "May"]
  • 구문:     array.splice(start[, deleteCount[, item1[, item2[, ...]]]])

  • 매개변수:
    • start: 배열의 원소 제거를 시작할 인덱스
    • deleteCount(optional): 제거할 원소의 수. 0이하일 땐 어떤 원소도 제거하지 않는다.
    • item1, item2, <em>...<em>(optional):배열에 추가할 원소
  • 반환값: 제거한 요소를 담은 배열. 
  • 하는 일: 배열 자기자신을 조작하여 기존의 원소를 삭제, 교체하거나 다른 원소를 추가한다.
  • 동작특징:
    • 복사하거나 하지 않고, 자기 자신을 직접적으로 조작함.
    • 배열의 원소를 추출하는 것 뿐만 아니라 원소를 교체 및 추가할 수 있다.
    • slice 함수 처럼, 음수 인수를 사용할 수 있다.

splice 메소드 같은 경우, 다양한 쓰임새를 직접보는 것이 좋을 것 같아서 MDN web docs에서 사용한 여러 예시들을 가져왔다. 아래의 더보기를 누르면 예시를 볼 수 있다.

더보기

1. 제거한 원소X, 2번 인덱스에 'drum' 추가

var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];
var removed = myFish.splice(2, 0, 'drum');

// myFish is ["angel", "clown", "drum", "mandarin", "sturgeon"]
// removed is [], no elements removed​

2. 제거한 원소X, 2번 인덱스에 'drum' 'guitar' 추가

var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];
var removed = myFish.splice(2, 0, 'drum', 'guitar');

// myFish is ["angel", "clown", "drum", "guitar", "mandarin", "sturgeon"]
// removed is [], no elements removed

3. 3번 인덱스에서 한 개 요소 제거

var myFish = ['angel', 'clown', 'drum', 'mandarin', 'sturgeon'];
var removed = myFish.splice(3, 1);

// removed is ["mandarin"]
// myFish is ["angel", "clown", "drum", "sturgeon"]

 4. 2번 인덱스에서 한 개 요소 제거하고 "trumpet" 추가

var myFish = ['angel', 'clown', 'drum', 'sturgeon'];
var removed = myFish.splice(2, 1, 'trumpet');

// myFish is ["angel", "clown", "trumpet", "sturgeon"]
// removed is ["drum"]

5. 0번 인덱스에서 두 개 요소 제거하고 "parrot", "anemone", "blue" 추가

var myFish = ['angel', 'clown', 'trumpet', 'sturgeon'];
var removed = myFish.splice(0, 2, 'parrot', 'anemone', 'blue');

// myFish is ["parrot", "anemone", "blue", "trumpet", "sturgeon"]
// removed is ["angel", "clown"]

6. 2번 인덱스에서 두 개 요소 제거

var myFish = ['parrot', 'anemone', 'blue', 'trumpet', 'sturgeon'];
var removed = myFish.splice(myFish.length - 3, 2);

// myFish is ["parrot", "anemone", "sturgeon"]
// removed is ["blue", "trumpet"]

7. -2번 요소에서 한 개 제거

var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];
var removed = myFish.splice(-2, 1);

// myFish is ["angel", "clown", "sturgeon"]
// removed is ["mandarin"]

 8. 2번 인덱스 부터 모든 요소 제거

var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];
var removed = myFish.splice(2);

// myFish is ["angel", "clown"]
// removed is ["mandarin", "sturgeon"]