[Modern JS Deep Dive] CH27-배열(2)

Boo Sung Jun·2022년 7월 29일
0

JavaScript

목록 보기
21/27
post-thumbnail

Modern JavaScript Deep Dive 스터디 - CH27 배열(2) :

배열 메서드

참고 자료: ⟪모던 자바스크립트 Deep Dive⟫(이웅모 지음,위키북스, 2020)


8. 배열 메서드

  • 배열 메서드는 두가지 패턴이 있음
    • mutator method: 원본배열을 직접 변경하는 메서드
    • accessor method: 원본배열을 직접 변경하지 않고 새로운 배열을 생성하여 반환하는 메서드
  • 가급적 원본 배열을 직접 변경하지 않는 메서드를 사용하는 편을 권장

1) Array.isArray

  • 인수가 배열이면 true, 배열이 아니면 false를 리턴
// true
Array.isArray([]);
Array.isArray([1, 2]);
Array.isArray(new Array());

// false
Array.isArray();
Array.isArray({});
Array.isArray(null);
Array.isArray(undefined);
Array.isArray(1);
Array.isArray("Array");
Array.isArray(true);
Array.isArray(false);
Array.isArray({ 0: 1, length: 1 });

2) Array.protptype.indexOf

  • 인수로 전달된 요소를 검색하여 인덱스를 리턴
  • 중복되는 요소가 여러개 있다면 첫번째로 검색된 요소의 인덱스를 리턴
  • 요소가 존재하지 않으면 -1 리턴
const arr = [1, 2, 2, 3];

// 배열 arr에서 요소 2를 검색하여 첫 번째로 검색된 요소의 인덱스를 반환한다.
arr.indexOf(2); // -> 1
// 배열 arr에 요소 4가 없으므로 -1을 반환한다.
arr.indexOf(4); // -> -1
// 두 번째 인수는 검색을 시작할 인덱스다. 두 번째 인수를 생략하면 처음부터 검색한다.
arr.indexOf(2, 2); // -> 2
  • NaN은 찾을 수 없음
console.log([NaN].indexOf(NaN)); // false

3) Array.prototpye.push

  • 원본 배열의 마지막 요소로 추가하고 변경된 length 프로퍼티 값을 반환
  • 원본 배열을 직접 변경
const arr = [1, 2];

// 인수로 전달받은 모든 값을 원본 배열 arr의 마지막 요소로 추가하고 변경된 length 값을 반환한다.
let result = arr.push(3, 4);
console.log(result); // 4

// push 메서드는 원본 배열을 직접 변경한다.
console.log(arr); // [1, 2, 3, 4]
  • 성능 면에서 좋지 않음 -> 배열의 마지막 요소에 직접 추가하거나 스프레드 문법 이용
const arr = [1, 2];

// arr.push(3)과 결과 동일
arr[arr.length] = 3;
console.log(arr); // [1, 2, 3]

const arr = [1, 2];

// ES6 스프레드 문법
const newArr = [...arr, 3];
console.log(newArr); // [1, 2, 3]

4) Array.prototype.pop

  • 마지막 요소를 제거하고 제거한 요소를 리턴
  • 원본 배열이 빈 배열이면 undefined를 리턴
  • 원본 배열을 직접 변경
const arr = [1, 2];

// 원본 배열에서 마지막 요소를 제거하고 제거한 요소를 반환한다.
let result = arr.pop();
console.log(result); // 2

// pop 메서드는 원본 배열을 직접 변경한다.
console.log(arr); // [1]

5) Array.prototype.unshift

  • 원본 배열의 선두에 요소로 추가
  • length 프로퍼티 값을 반환
  • 원본 배열을 직접 변경
const arr = [1, 2];

// 인수로 전달받은 모든 값을 원본 배열의 선두에 요소로 추가하고 변경된 length 값을 반환한다.
let result = arr.unshift(3, 4);
console.log(result); // 4

// unshift 메서드는 원본 배열을 직접 변경한다.
console.log(arr); // [3, 4, 1, 2]

6) Array.prototype.shift

  • 배열에서 첫 번째 요소를 제거하고 제거한 요소를 반환
  • 원본 배열이 빈 배열이면 undefined를 반환
  • 원본 배열을 직접 변경
const arr = [1, 2];

// 원본 배열에서 첫 번째 요소를 제거하고 제거한 요소를 반환한다.
let result = arr.shift();
console.log(result); // 1

// shift 메서드는 원본 배열을 직접 변경한다.
console.log(arr); // [2]

7) Array.prototype.concat

  • 인수로 값들이 전달된 경우, 원본 배열의 마지막 요소로 추가한 새로운 배열을 반환
  • 인수로 배열이 전달된 경우, 배열을 해체하고 추가한 새 배열을 반환
  • 원본 배열은 변경되지 않음
const arr1 = [1, 2];
const arr2 = [3, 4];

// 배열 arr2를 원본 배열 arr1의 마지막 요소로 추가한 새로운 배열을 반환한다.
// 인수로 전달한 값이 배열인 경우 배열을 해체하여 새로운 배열의 요소로 추가한다.
let result = arr1.concat(arr2);
console.log(result); // [1, 2, 3, 4]

// 숫자를 원본 배열 arr1의 마지막 요소로 추가한 새로운 배열을 반환한다.
result = arr1.concat(3);
console.log(result); // [1, 2, 3]

// 배열 arr2와 숫자를 원본 배열 arr1의 마지막 요소로 추가한 새로운 배열을 반환한다.
result = arr1.concat(arr2, 5);
console.log(result); // [1, 2, 3, 4, 5]

// 원본 배열은 변경되지 않는다.
console.log(arr1); // [1, 2]
  • 스프레드 문법으로 대체 가능
let res = [1, 2].concat([3, 4]);
let res = [...[1, 2], ...[3, 4]];

8) Array.prototype.splice

  • 원본 배열 중간에 요소를 추가하거나 중간에 있는 요소를 제거
  • 제거한 요소가 배열로 반환
  • 원본 배열을 직접 변경
  • 3개의 매개변수가 있음
    Array.splice(start, deletecount, items);
    • start: 제거 시작할 인덱스
    • deletecount(option): 제거할 요소의 개수
    • items(option): 제거한 위치에 삽입할 요소들의 목록
const arr1 = [1, 2, 3, 4];

// 원본 배열의 인덱스 1부터 2개의 요소를 제거하고 그 자리에 새로운 요소 20, 30을 삽입한다.
const result1 = arr1.splice(1, 2, 20, 30);

// 제거한 요소가 배열로 반환된다.
console.log(result1); // [2, 3]
// splice 메서드는 원본 배열을 직접 변경한다.
console.log(arr1); // [1, 20, 30, 4]

const arr2 = [1, 2, 3, 4];

// 원본 배열의 인덱스 1부터 0개의 요소를 제거하고 그 자리에 새로운 요소 100을 삽입한다.
const result2 = arr2.splice(1, 0, 100);

// 원본 배열이 변경된다.
console.log(arr2); // [1, 100, 2, 3, 4]
// 제거한 요소가 배열로 반환된다.
console.log(result2); // []

const arr3 = [1, 2, 3, 4];

// 원본 배열의 인덱스 1부터 2개의 요소를 제거한다.
const result3 = arr3.splice(1, 2);

// 원본 배열이 변경된다.
console.log(arr3); // [1, 4]
// 제거한 요소가 배열로 반환된다.
console.log(result3); // [2, 3]

const arr4 = [1, 2, 3, 4];

// 원본 배열의 인덱스 1부터 모든 요소를 제거한다.
const result4 = arr4.splice(1);

// 원본 배열이 변경된다.
console.log(arr4); // [1]
// 제거한 요소가 배열로 반환된다.
console.log(result4); // [2, 3, 4]

9) Array.prototype.slice

  • splice 메소드와 이름 혼동 주의
  • 요소들을 복사하여 배열로 반환
  • 원본 배열은 변경되지 않음
  • 얕은 복사(shallow copy)
  • 2개의 매개변수 가짐
    Array.prototype.slice(start, end)

    start: 복사 시작 인덱스
    end: 복사 종료 인덱스. 생략 시 기본 값은 length 프로퍼티 값
    인수를 모두 생략하면 원본 배열의 복사본을 생성

const arr = [1, 2, 3];

// arr[0]부터 arr[1] 이전(arr[1] 미포함)까지 복사하여 반환한다.
arr.slice(0, 1); // -> [1]

// arr[1]부터 arr[2] 이전(arr[2] 미포함)까지 복사하여 반환한다.
arr.slice(1, 2); // -> [2]

// 원본은 변경되지 않는다.
console.log(arr); // [1, 2, 3]
const arr = [1, 2, 3];

// 배열의 끝에서부터 요소를 한 개 복사하여 반환한다.
arr.slice(-1); // -> [3]

// 배열의 끝에서부터 요소를 두 개 복사하여 반환한다.
arr.slice(-2); // -> [2, 3]
const todos = [
  { id: 1, content: "HTML", completed: false },
  { id: 2, content: "CSS", completed: true },
  { id: 3, content: "Javascript", completed: false },
];

// 얕은 복사(shallow copy)
const _todos = todos.slice();
// const _todos = [...todos];

// _todos와 todos는 참조값이 다른 별개의 객체다.
console.log(_todos === todos); // false

// 배열 요소의 참조값이 같다. 즉, 얕은 복사되었다.
console.log(_todos[0] === todos[0]); // true

10) Array.prototype.join

  • 원본 배열의 모든 요소를 구분자로 연결한 문자열을 반환
  • 구분자는 생략 가능
  • 기본 구분자는 콤마(,)
const arr = [1, 2, 3, 4];

// 기본 구분자는 ','이다.
// 원본 배열 arr의 모든 요소를 문자열로 변환한 후, 기본 구분자 ','로 연결한 문자열을 반환한다.
arr.join(); // -> '1,2,3,4';

// 원본 배열 arr의 모든 요소를 문자열로 변환한 후, 빈문자열로 연결한 문자열을 반환한다.
arr.join(""); // -> '1234'

// 원본 배열 arr의 모든 요소를 문자열로 변환한 후, 구분자 ':'로 연결한 문자열을 반환한다.ㄴ
arr.join(":"); // -> '1:2:3:4'

11) Array.prototype.reverse

  • 원본 배열의 순서를 반대로 뒤집음
  • 원본 배열이 변경
  • 변경된 배열을 반환
const arr = [1, 2, 3];
const result = arr.reverse();

// reverse 메서드는 원본 배열을 직접 변경한다.
console.log(arr); // [3, 2, 1]
// 반환값은 변경된 배열이다.
console.log(result); // [3, 2, 1]

12) Array.prototype.fill

  • 인수로 전달받은 값을 배열의 처음부터 끝까지 요소로 채움
  • 원본 배열이 변경
const arr = [1, 2, 3];

arr.fill(0);
console.log(arr); // [0, 0, 0]

// 인수로 전달받은 값 0을 배열의 인덱스 1부터 끝까지 요소로 채운다.
arr.fill(0, 1);
// fill 메서드는 원본 배열을 직접 변경한다.
console.log(arr); // [1, 0, 0]

const arr = [1, 2, 3, 4, 5];

// 인수로 전달받은 값 0을 배열의 인덱스 1부터 3 이전(인덱스 3 미포함)까지 요소로 채운다.
arr.fill(0, 1, 3);
// fill 메서드는 원본 배열을 직접 변경한다.
console.log(arr); // [1, 0, 0, 4, 5]
  • 배열을 생성하면서 특정 값으로 요소를 채울 수 있음
const arr = new Array(3);
console.log(arr); // [empty × 3]

// 인수로 전달받은 값 1을 배열의 처음부터 끝까지 요소로 채운다.
const result = arr.fill(1);

// fill 메서드는 원본 배열을 직접 변경한다.
console.log(arr); // [1, 1, 1]

// fill 메서드는 변경된 원본 배열을 반환한다.
console.log(result); // [1, 1, 1]

// === 다른 방식 ===
// 인수로 전달받은 정수만큼 요소를 생성하고 0부터 1씩 증가하면서 요소를 채운다.
const sequences = (length = 0) => Array.from({ length }, (_, i) => i);
// const sequences = (length = 0) => Array.from(new Array(length), (_, i) => i);

console.log(sequences(3)); // [0, 1, 2]

13) Array.prototype.includes

  • 특정 요소가 포함되어 있는지 확인
  • 2개의 매개변수 가짐
    • 첫 번째 매개변수: 검색 대상
    • 두 번째 매개변수: 검색 시작 인덱스
const arr = [1, 2, 3];

// 배열에 요소 2가 포함되어 있는지 확인한다.
arr.includes(2); // -> true

// 배열에 요소 100이 포함되어 있는지 확인한다.
arr.includes(100); // -> false

const arr = [1, 2, 3];

// 배열에 요소 1이 포함되어 있는지 인덱스 1부터 확인한다.
arr.includes(1, 1); // -> false

// 배열에 요소 3이 포함되어 있는지 인덱스 2(arr.length - 1)부터 확인한다.
arr.includes(3, -1); // -> true
  • NaN도 확인 가능
[NaN].indexOf(NaN) !== -1; // -> false
[NaN].includes(NaN); // -> true

14) Array.prototype.flat

  • 인수로 전달한 깊이 만큼 재귀적으로 배열을 평탄화
  • 인수를 생략할 경우 기본값은 1
  • 인수로 Infinity를 전달하면 중첩 배열 모두를 평탄화
[1, [2, 3, 4, 5]].flat(); // -> [1, 2, 3, 4, 5]

// 중첩 배열을 평탄화하기 위한 깊이 값의 기본값은 1이다.
[1, [2, [3, [4]]]].flat(); // -> [1, 2, [3, [4]]]
[1, [2, [3, [4]]]].flat(1); // -> [1, 2, [3, [4]]]

// 중첩 배열을 평탄화하기 위한 깊이 값을 2로 지정하여 2단계 깊이까지 평탄화한다.
[1, [2, [3, [4]]]].flat(2); // -> [1, 2, 3, [4]]
// 2번 평탄화한 것과 동일하다.
[1, [2, [3, [4]]]].flat().flat(); // -> [1, 2, 3, [4]]

// 중첩 배열을 평탄화하기 위한 깊이 값을 Infinity로 지정하여 중첩 배열 모두를 평탄화한다.
[1, [2, [3, [4]]]].flat(Infinity); // -> [1, 2, 3, 4]

0개의 댓글