27장 배열

이로그·2024년 1월 28일
0

27장 배열

27.1 배열이란?

  • 배열은 여러 개의 값을 순차적으로 나열한 자료구조다.
  • 자바스크립트의 모든 값은 배열의 요소가 될 수 있다.
  • 배열의 요소는 배열에서 자신으 위치를 나타내는 0 이상의 정수인 인덱스를 갖는다.
  • 배열은 배열의 길이를 나타내는 length 프로퍼티를 갖는다.
  • 인덱스와 length를 갖고 때문에 for문을 통해 순차적으로 접근할 수 있다.
  • 일반 객체와 배열을 구분하는 가장 명확한 차이는 값의 순서length 프로퍼티 다.
  • 자바스크리트에 배열이라는 타입은 존재하지 않는다. 배열은 객체 타입이다.
  • 배열은 배열 리터럴, Array 생성자 함수, Array.of, Array.from 메서드로 생성할 수 있다.
  • 배열의 프로토타입 객체는 Array.prototype 이다.
const arr = ['apple', 'banana', 'orange'];

console.log(arr[0]); // apple
console.log(arr[1]); // banana
console.log(arr[2]); // orange

console.log(arr.length); // 3

for(let i = 0; i < arr.length; i++) {
    console.log(arr[i]); // 'apple' 'banana' 'orange'
}

console.log(typeof arr); // object

console.log(arr.constructor === Array); // true
console.log(Object.getPrototypeOf(arr) === Array.prototype) // true

27.2 자바스크립트 배열은 배열이 아니다.

  • 자료구조에서 말하는 배열은 동일한 크기의 메모리 공간이 빈틈없이 연속적으로 나열된 자료구조를 말한다. 이러한 배열을 밀집 배열이라고 한다.
  • 자바스크립트의 배열은 동일한 크기를 갖지 않고, 연속적으로 이어져 있지 않을 수도 있는 희소 배열이다.
  • 자바스크립트의 배열은 일반적인 배열의 동작을 흉내 낸 특수한 객체다.
  • 자바스크립트에서 사용할 수 있는 모든 값은 객체의 프로퍼티 값이 될 수 있으므로 어떤 타입의 값이라도 배열의 요소가 될 수 있다.
const arr = [
    'string',
    10,
    true,
    null
    undefined,
    NaN,
    Infinity,
    [],
    {},
    function(){}
];
  • 자바스크립트 배열은 인덱스로 배열 요소에 접근하는 경우에는 일반적인 배열보다 느리지만, 특정 요소를 검색하거나 요소를 삽입/삭제 할 경우 일반적인 배열보다 빠르다.

27.3 length 프로퍼티와 희소 배열

  • length 프로퍼티는 요소의 개수, 즉 배열의 길이를 나타내는 0 이상의 정수를 값으로 갖는다.
  • 빈 배열일 경우 0, 빈 배열이 아닐 경우 가장 큰 인덱스에 1을 더한 것과 같다.
  • length 프로퍼티의 값은 배열에 요소를 추가/삭제하면 자동 갱신 된다.
  • length 프로퍼티값은 임의의 숫자 값으로 명시적으로 할당할 수도 있는데, 값보다 작은 숫자 값을 할당하면 배열의 길이가 줄어든다.
  • length 프로퍼티값보다 큰 숫자 값을 할당하는 경우, 실제로 배열의 길이가 늘어나지는 않는다.
const arr = [1, 2, 3, 4, 5];

arr.length = 3;

console.log(arr); // [1, 2, 3]
  • 배열의 요소가 연속적으로 위치하지 않고 일부가 비어 있는 배열을 희소 배열이라 한다.
  • 희소 배열은 length와 배열의 요소의 개수가 일치하지 않는다. 희소 배열의 length는 희소 배열의 실제 요소 개수보다 언제나 크다.
  • 배열에는 같은 타입의 요소를 연속적으로 위치시키는 것이 최선이다.

27.4 배열 생성

27.4.1 배열 리터럴

  • 배열 리터럴은 0개 이상의 요소를 쉼표로 구분하여 대괄호([])로 묶는다.
  • 요소를 하나도 추가하지 않으면 length 프로퍼티 값이 0인 빈 배열이 된다.
const arr = [1, 2, 3];
console.log(arr.length); // 3

const arr2 = [];
console.log(arr2.length); // 0

27.4.2 Array 생성자 함수

  • Array 생성자 함수를 통해 배열을 생성할 수도 있다.
  • Array 생성자 함수는 전달된 인수의 개수에 따라 다르게 동작하므로 주의가 필요하다.
  • 전달된 인수가 1개이고, 숫자인 경우 length 프로퍼티 값이 인수인 배열을 생성한다
const arr = new Array(10);

console.log(arr); // [empty x 10]
console.log(arr.length); // 10
  • 전달된 인수가 없으면 빈 배열을 생성한다.
const arr = new Array();
  • 전달된 인수가 2개 이상이거나 숫자가 아닌 경우 인수를 요소로 갖는 배열을 생성한다.
const arr = new Array(1, 2, 3); // [1, 2, 3]
const arr2 = new Array({}); // [{}]
  • Array 생성자 함수는 함수 내부에서 new.target을 확인하기 때문에 new 연산자와 함께 호출하지 않아도 배열을 생성할 수 있다.

27.4.3 Array.of

  • ES6에서 도입된 Array.of 메서드는 전달된 인수를 요소로 갖는 배열을 생성한다.
  • 전달된 인수가 1개이고, 숫자이더라도 인수를 요소로 갖는 배열을 생성한다.
Array.of(1); // [1]
Array.of(1, 2, 3); // [1, 2, 3]
Array.of('string'); // ['string']

27.4.4 Array.from

  • ES6에서 도입된 Array.from 메서드는 유사 배열 객체 또는 이터러블 객체를 인수로 전달받아 배열로 변환하여 반환한다.
Array.from({length: 2, 0: 'a', 1: 'b'}); // ['a', 'b']
Array.from('Hello'); // ['H', 'e', 'l', 'l', 'o']
  • 두번째 인수로 전달한 콜백함수르 통해 값을 만들면서 요소를 채울 수 있다.
Array.from({length: 3}, (_, i) => i); // [0, 1, 2]

27.5 배열 요소의 참조

  • 배열의 요소를 참조할 때에는 대괄호([]) 표기법을 사용한다. 대괄호 안에는 인덱스가 와야 한다.
  • 존재하지 않는 요소에 접근하면 undefined가 반환된다.
const arr = [1, 2];
console.log(arr[1]); // 2
console.log(arr[3]); // undefined

27.6 배열 요소의 추가와 갱신

  • 배열에도 요소를 동적으로 추가할 수 있다. 이때 length 프로퍼티 값은 자동 갱신된다.
  • 존재하지 않는 인덱스를 사용해 값을 할당하면 새로운 요소가 추가된다.
  • 이미 요소가 존재하는 요소에 값을 재할당하면 요소값이 갱신된다.
  • 인덱스는 반드시 0 이상의 정수를 사용해야 한다. 만약 정수 이외의 값을 인덱스처럼 사용하면 프로퍼티가 생성 된다. length 프로퍼티에 아무런 영향을 주지 않는다.
const arr = [0];

arr[1] = 1;

console.log(arr); // [0, 1]
console.log(arr.length); // 2

arr[0] = 10;
console.log(arr); // [10, 1]

arr['foo'] = 2;

console.log(arr); // [10, 1, foo: 2]
console.log(arr.length); // 2

27.7 배열 요소의 삭제

  • 배열 또한 객체이기 때문에 delete 연산자를 사용하여 삭제할 수 있다.
  • 사용에 따라 delete 연산자를 이용한 삭제는 희소배열을 만들기 때문에 권장하지 않는다.
  • length 프로퍼티에 영향을 주지 않는다.
const arr = [1, 2, 3];

delete arr[1];
console.log(arr); // [1, empty, 3]

console.log(arr.length); // 3
  • Array.prototype.splice 메서드를 사용하면 희소 배열을 만들지 않으며서 특정 요소를 완전히 삭제 가능하다.
const arr = [1, 2, 3];

// arr[1]부터 1개의 요소를 제거
arr.splice(1, 1);
console.log(arr); // [1, 3]
console.log(arr.length); // 2

27.8 배열 메서드

  • 자바스크립트는 배열을 다룰 때 유용한 다양한 빌트인 메서드를 제공한다.
  • 이때 결과물을 반환하는 패턴이 두가지이므로 주의가 필요하다.
    • 원본 배열을 직접 변경하는 메서드
    • 원본 배열을 직접 변경하지 않고 새로운 배열을 생성하여 반환하는 메서드
  • 원본 배열을 직접 변경하는 메서드는 외부 상태를 직접 변경하는 부수 효과가 있으므로 가급적 원본 배열을 직접 변경하지 않는 메서드를 사용하는 편이 좋다.

27.8.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);

27.8.2 Array.prototype.indexOf

  • indexOf 메서드는 원본 배열에서 인수로 전달된 요소를 검색하여 인덱스를 반환한다.
  • 인수로 전달한 요소가 존재하지 않으면 -1을 반환한다.
  • 배열에 특정 요소가 존재하는지 확인할 때 유용하다.
const arr = [1, 2, 2, 3];

arr.indexOf(2); // 1
arr.indexOf(4); // -1
// 두번째 인수는 검색을 시작할 인덱스임.
arr.indexOf(2, 2); // 2

const foods = ['apple', 'banana', 'orange'];
if(foods.indexOf('orange') === -1) {
  foods.push('orange);
}

console.log(foods); // ['apple', 'banana', 'orange'];

27.8.3 Array.prototype.push

  • push 메서드는 배열의 마지막 요소로 추가하고, length값을 반환한다.
  • push 메서드는 원본 배열을 직접 변경한다. 따라서 push 메서드보다 ES6의 스프레드 문법을 사용하는 편이 좋다.
  • push 메서드는 성능면에서 좋지 않다. length 프로퍼티를 사용하여 배열의 마지막에 요소를 직접 추가할 수 있는데, 이 방법이 push 메서드보다 빠르다.
const arr = [1, 2];

let result = arr.push(3, 4);
console.log(result); // 4

console.log(arr); // [1, 2, 3, 4]

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

27.8.4 Array.prototype.pop

  • pop 메서드는 배열의 마지막 요소를 제거하고, 제거한 요소를 반환한다.
  • pop 메서드는 원본 배열을 직접 변경한다.
const arr = [1, 2];

let result = arr.pop();
console.log(result); // 2

console.log(arr); // [1]

27.8.5 Array.prototype.unshift

  • unshift 메서드는 인수로 전달받은 모든 값을 원본 배열의 선두에 요소로 추가하고, length값을 반환한다.
  • unshift 메서드는 원본 배열을 직접 변경하는 부수 효과가 있기 때문에 ES6의 스프레드 문법을 사용하는 편이 좋다.
const arr = [1, 2];

let result = arr.unshift(3, 4);
console.log(result); // 4

console.log(arr); // [3, 4, 1, 2]

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

27.8.6 Array.prototype.shift

  • shift 메서드는 원본 배열에서 첫 번째 요소를 제거하고 제거한 요소를 반환한다.
  • shift 메서드는 원본 배열을 직접 변경한다.
const arr = [1, 2];

let result = arr.shift();
console.log(result); // 1

console.log(arr); // [2]

27.8.7 Array.prototype.concat

  • concat 메서드는 인수로 전달된 값들을 원본 배열의 마지막 요소로 추가한 새로운 배열을 반환한다.
  • 인수로 전달한 값이 배열인 경우 배열을 해체하여 새로운 배열의 요소로 추가한다.
  • 원본 배열은 변경되지 않는다.
  • concat을 사용할 경우 반드시 반환 값을 변수에 할당 받아야 한다.
  • concat 메서드는 ES6의 스프레드 문법으로 대체 할 수 있다.
const arr1 = [1, 2];
const arr2 = [3, 4];

let result = arr1.concat(arr2);
console.log(result); // [1, 2, 3, 4]

result = arr1.concat(3);
console.log(result); // [1, 2, 3]

result = arr1.concat(arr2, 5);
console.log(result); // [1, 2, 3, 4, 5]

console.log(arr1); // [1, 2]

result = [...arr1, ...[3, 4]];
console.log(result); // [1, 2, 3, 4]

27.8.8 Array.prototype.splice

  • splice 메서드는 배열의 중간에 요소를 추가하거나 중간에 있는 요소를 제거하는 경우 사용한다.

array.splice(start[, deleteCount][, items])

  • splice 메서드는 3개의 매개변수가 있으면 원본 배열을 직접 변경한다
    • start : 원본 배열의 요소를 제거하기 시작할 인덱스. 음수일 경우 배열의 끝에서 인덱스를 시작한다. -1이 마지막 요소, -n이 마지막에서 n번째 요소
    • deleteCount : 원본 배열의 요소를 제거하기 시작할 인덱스인 start로부터 제거할 요소의 개수. 만약 0이면 아무런 요소도 제거하지 않고 새로운 요소들을 삽입한다. 만약 아무것도 전달하지 않으면, start 인덱스 부터 모든 요소를 제거 한다.
    • items : 제거한 위치에 삽입할 요소들의 목록. 아무것도 전달하지 않으면 원본 배열에서 지정된 요소를 제거하기만 한다.
let arr = [1, 2, 3, 4];

// 인덱스 1부터 2개의 요소를 삭제하고 그 자리에 20, 30을 삽입한다.
let result = arr.splice(1, 2, 20, 30);;

console.log(result); // [2, 3]
console.log(arr); // [1, 20, 30, 4]

result = arr.splice(2, 0, 100);

console.log(result); // []
console.log(arr); // [1, 2, 100, 20, 30]

result = arr.splice(3, 2);

console.log(result); // [20, 30]
console.log(arr); // [1, 2, 100]

result = arr.splice(1);
console.log(result); // [2, 100]
console.log(arr); // [1]
  • 보통 배열에서 특정 요소를 제거 하려면 indexOf로 특정 요소의 인덱스를 취득하여 splice를 사용한다.
const arr = [1, 2, 3, 1, 2];

const index = arr.indexOf(2);
const result = arr.splice(index, 1);

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

27.8.9 Array.prototype.slice

  • slice 메서드는 인수로 전달된 범위의 요소들을 복사하여 배열로 반환한다.
  • 원본 배열은 변경되지 않는다.

array.slice(start, end)

  • start : 복사를 시작할 인덱스. 음수인 경우 배열의 끝에서 인덱스를 시작한다.
  • end : 복사를 종료할 인덱스. 이 인덱스에 해당하는 요소는 복사되지 않는다. end는 생략 가능하며, 생략시 기본 값은 length 프로퍼티 값이다.
  • 인수값 모두 생략 시 원본 배열의 복사본을 생성하여 반환함. 이때 복사는 얕은 복사를 통해 생성 된다.
const arr = [1, 2, 3];

// arr[0]부터 arr[1] 전까지 복사한 값 반환
arr.slice(0, 1); // [1]
// arr[1]부터 arr[2] 전까지 복사한 값 반환
arr.slice(1, 2); // [2]

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

// arr[1]부터 이후의 모든 요소 복사
arr.slice(1); // [2, 3]

const copy = arr.slice();
console.log(copy); // [1, 2, 3]
console.log(arr === copy); // false

27.8.10 Array.prototype.join

  • join 메서드는 원본 배열의 모든 요소를 문자열로 변환한 후, 인수로 전달받은 문자열로 연결한 문자열을 반환한다. 기본 구분자는 콤마(',')다.
const arr = [1, 2, 3, 4];

arr.join(); // '1,2,3,4'
arr.join(''); //'1234'
arr.join(':'); // '1:2:3:4'

27.8.11 Array.prototype.reverse

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

console.log(arr); // [3, 2, 1]
console.log(result); // [3, 2, 1]

27.8.12 Array.prototype.fill

  • ES6에서 도입된 fill 메서드는 인수로 전달 받은 값을 배열의 처음부터 끝까지 요소로 채운다.
  • 원본 배열이 변경된다.
const arr = [1, 2, 3, 4, 5];

// 인수로 전달받은 값 0을 배열의 인덱스 1부터 끝까지 요소로 채운다.
arr.fill(0, 1);
console.log(arr); // [1, 0, 0, 0, 0]

// 인수로 전달받은 값 2을 배열의 인덱스 1부터 3이전까지 요소로 채운다.
arr.fill(2, 1, 3);
console.log(arr); // [1, 2, 2, 0, 0]

27.8.13 Array.prototype.includes

  • includes 메서드는 배열 내에 특정 요소가 포함되어 있는지 확인하여 true 또는 false를 반환한다.
  • 두번째 인수로 검색을 시작할 인덱스를 전달 할 수 있다. 만약 두번째 인수에 음수를 전달하면 length 프로퍼티 값과 음수 인덱스를 합산하여 검색 시작 인덱스를 설정한다.
const arr = [1, 2, 3];

arr.includes(2); // true
arr.includes(100); // false

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

// 배열에 요소 3이 포함되어 있는지 인덱스 2(arr.length - 1) 부터 확인.
arr.includes(3, -1); // true

27.8.14 Array.prototype.flat

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

[1, [2, [3, [4]]]].flat(2); // [1, 2, 3, [4]]
[1, [2, [3, [4]]]].flat().flat(); // [1, 2, 3, [4]]

[1, [2, [3, [4]]]].flat(Infinity); // [1, 2, 3, 4]

27.9 배열 고차 함수

  • 고차 함수는 함수를 인수로 전달 받거나 함수를 반환하는 함수를 말한다.
  • 고차 함수는 외부 상태의 변경이나 가변 데이터를 피하고 불변성을 지향하는 함수평 프로그래밍에 기반을 두고 있다.
  • 함수형 프로그래밍은 결국 순수 함수를 통해 부수 효과를 최대한 억제하고 오류를 피하고 프로그램의 안정성을 높이려는 노력의 일환이라고 할 수 있다.

27.9.1 Array.prototype.sort

  • sort 메서드는 배열의 요소를 정렬한다.
  • 원본 배열을 직접 변경하며 정렬된 배열을 반환한다.
  • 기본적으로 오름차순으로 요소를 정렬한다.
  • 한글 문자인 요소도 오름차순으로 정렬된다.
const fruits = ['Banana', 'Orange', 'Apple'];
const fruitsKor = ['바나나', '오렌지', '사과'];

fruits.sort();
fruitsKor.sort();

console.log(fruits); // ['Apple', 'Banana', 'Orange']
console.log(fruitsKor); // ['바나나', '사과', '오렌지']
  • sort 메서드의 기본 정렬 순서는 유니코드 코드 포인트의 순서를 따른다. 숫자 타입이라면 일시적으로 문자열로 변환 후 유니코드 코드 포인트의 순서를 기준으로 정렬한다.
  • 따라서 숫자 요소로 이루어진 배열을 정렬할 때는 주의가 필요하다. 정렬 순서를 정의하는 비교 함수를 인수로 전달해야 한다.
  • 비교 함수의 반환값이 0보다 작으면, 비교 함수의 첫 번째 인수를 우선으로 정렬
  • 비교 함수의 반환값이 0이면 정렬하지 않으며,
  • 비교 함수의 반환값이 0보다 크면 두 번째 인수를 우선하여 정렬한다.
const points = [40, 100, 1, 5, 2, 25, 10];

// 숫자 배열의 오름차순 정렬. 비교 함수의 반환값이 0보다 작으면 a를 우선으로 정렬
points.sort((a, b) => a - b);
console.log(points); // [1, 2, 5, 10, 25, 40, 100]

// 숫자 배열의 내림차순 정렬. 비교 함수의 반환값이 0보다 작으면 b를 우선으로 정렬
points.sort((a, b) => b - a);
console.log(points); // [100, 40, 25, 10, 5, 2, 1]

27.9.2 Array.prototype.forEach

  • forEach 메서드는 for문을 대체할 수 있는 고차 함수다.
  • forEach 메서드는 반복문을 추상화한 고차 함수로서 내부에서 반복문을 통해 자신을 호출한 배열을 순회하면서 수행해야 할 처리를 콜백 함수로 전달받아 반복 호출한다.
const numbers = [1, 2, 3];
const pows = [];

numbers.forEach(item => pows.push(item ** 2));
console.log(pows); // [1, 4, 9]
  • forEach 메서드는 콜백 함수로 호출하면서 3개의 인수를 전달한다.
[1, 2, 3].forEach((item, index, arr) => {
  console.log(`요소값 : ${item}, 인덱스 : ${index}, this : ${JSON.stringify(arr)}`)
})
/*
요소값 : 1, 인덱스 : 0, this : [1,2,3]
요소값 : 2, 인덱스 : 1, this : [1,2,3]
요소값 : 3, 인덱스 : 2, this : [1,2,3]
*/
  • forEach 메서드는 원본 배열을 변경하지 않는다. 하지만 콜백 함수를 통해 원본 배열을 변경할 수는 있다.
  • forEach 메서드에 this를 전달 하는 방법은 2가지가 있다.
    • forEach 메서드의 두번 째 인수로 this를 전달하는 방법
class Numbers {
  numberArray = [];

  multiply(arr) {
    arr.forEach(function (item) {
      // forEach의 콜백 함수가 일반 함수로 호출 되면 this를 제대로 가리키지 못하기 때문에 TypeError가 뜬다.
      // forEach 메서드의 콜백 함수 내부에서 this로 사용할 객체를 전달
      this.numberArray.push(item * item);
    }, this); 
  }
}

const numbers = new Numbers();
numbers.multiply([1, 2, 3]);
console.log(numbers.numberArray); // [1, 4, 9]
  • 화살표 함수를 사용하는 방법
class Numbers {
  numberArray = [];

  multiply(arr) {
    arr.forEach((item) => this.numberArray.push(item * item)); 
  }
}

const numbers = new Numbers();
numbers.multiply([1, 2, 3]);
console.log(numbers.numberArray); // [1, 4, 9]
  • forEach 메서드는 break, continue 문을 사용할 수 없다.
  • forEach 메서드는 for문에 비해 성능이 좋지는 않지만 가독성은 더 좋다.

27.9.3 Array.prototype.map

  • map 메서드는 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백 함수를 반복 호출 한다.
  • 그리고 콜백 함수의 반환값들로 구성된 새로운 배열을 반환한다. 원본 배열은 변경되지 않는다.
const numbers = [1, 4, 9];

const roots = numbers.map(item => Math.sqrt(item));

console.log(roots); // [1, 2, 3]
console.log(numbers); // [1, 4, 9]
  • 언뜻 봐서는 forEach와 비슷해보이지만, forEach는 언제나 undefined를 반환하고, map은 새로운 배열을 반환하는 차이가 있다.
  • map 메서드가 생성하여 반환하는 새로운 배열의 length 프로퍼티 값은 map 메서드를 호출한 배열의 length 프로퍼티 값과 반드시 일치한다. 즉, map 메서드를 호출한 배열과 map 메서드가 생성하여 반환한 배열은 1:1 매핑한다.
  • map 메서드는 콜백 함수로 호출하면서 3개의 인수를 전달한다.
[1, 2, 3].map((item, index, arr) => {
  console.log(`요소값 : ${item}, 인덱스 : ${index}, this : ${JSON.stringify(arr)}`);
  return item;
})
/*
요소값 : 1, 인덱스 : 0, this : [1,2,3]
요소값 : 2, 인덱스 : 1, this : [1,2,3]
요소값 : 3, 인덱스 : 2, this : [1,2,3]
*/
  • forEach와 동일하게 두번째 인자로 this를 전달 할 수 있다.

Array.prototype.filter

  • filter 메서드는 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달 받은 콜백 함수를 반복 호출한다.
  • 그리고 콜백 함수의 반환값이 true인 요소로만 구성된 새로운 배열을 반환한다. 원본 배열은 변경되지 않는다.
const numbers = [1, 2, 3, 4, 5];

const odds = nubmers.filter(item => item % 2);
console.log(odds); // [1, 3, 5]
  • filter 메서드가 생성하여 반환한 새로운 배열의 length 프로퍼티 값은 filter 메서드를 호출 배열의 length 프로퍼티 값과 같거나 작다.
  • filter 메서드는 콜백 함수로 호출하면서 3개의 인수를 전달한다.
[1, 2, 3].filter((item, index, arr) => {
  console.log(`요소값 : ${item}, 인덱스 : ${index}, this : ${JSON.stringify(arr)}`);
  return item % 2;
})
/*
요소값 : 1, 인덱스 : 0, this : [1,2,3]
요소값 : 2, 인덱스 : 1, this : [1,2,3]
요소값 : 3, 인덱스 : 2, this : [1,2,3]
*/

27.9.5 Array.prototype.reduce

  • reduce 메서드는 자신을 호출한 배열을 모든 요소를 순회하여 인수로 전달받은 콜백 함수를 반복 호출 한다.
  • 콜백 함수의 반환값을 다음 순회시에 콜백 함수의 첫번째 인수로 전달하면서 콜백 함수를 호출하여 하나의 결과값을 만들어 반환한다. 원본 배열은 변경되지 않는다.
  • reduce 메서드는 첫번째 인수로 콜백 함수, 두번째 인수로 초기값을 전달 받는다.
  • 콜백 함수에는 4개의 인수, 초기값 또는 콜백 함수의 이전 반환값, reduce 메서드를 호출한 배열의 요소값과 인덱스, reduce 메서드를 호출한 배열 자체(this)가 전달된다.
const sum = [1, 2, 3, 4].reduce((accumulator, currentValue, index, array) => {
  return accumulator + currentValue;
}, 0);

console.log(sum); // 10
  • reduce 메서드를 호출할 때는 언제나 초기값을 전달하는 것이 안전하다.

27.9.6 Array.prototype.some

  • some 메서드는 자신을 호출한 배열의 요소를 순회하면서 인수로 전달된 콜백 함수를 호출한다.
  • some 메서드는 콜백 함수의 반환값이 단 한번이라도 참이면 true, 모두 거짓이면 false를 반환한다.
  • 배열의 요소중에서 콜백 함수를 통해 정의한 조건을 만족하는 요소가 1개 이상 존재하는지 확인하여 그 결과를 불리언 타입으로 반환한다.
  • 배열이 빈 배열인 경우 언제나 false를 반환하므로 주의하자.
[5, 10, 15].some(item => item > 10); // true
[5, 10, 15].some(item => item < 10); // false

27.9.7 Array.prototype.every

  • every 메서드는 자신을 호출한 배열의 요소를 순회하면서 인수로 전달된 콜백 함수를 호출한다.
  • every 메서드는 콜백 함수의 모든 반환값이 모두 참이면 true, 단 한번이라도 거짓이면 false를 반환한다.
  • 배열의 모든 요소가 콜백 함수를 통해 정의한 조건을 모두 만족하는지 확인하여 그 결과를 불리언 타입으로 반환한다.
[5, 10, 15].every(item => item > 3); //true
[5, 10, 15].every(item => item > 10); //false

27.9.8 Array.prototype.find

  • find 메서드는 자신을 호출한 배열의 요소를 순회하면서 인수로 전달된 콜백 함수를 호출하여 반환값이 true인 첫 번째 요소를 반환한다.
  • true인 요소가 없다면 undefined를 반환한다.
const user = [
  { id: 1, name: 'Lee' },
  { id: 2, name: 'Kim' },
  { id: 2, name: 'Choi' },
  { id: 3, name: 'Park' },
];

user.find(user => user.id === 2); // {id: 2, name: 'Kim'}

27.9.9 Array.prototype.findIndex

  • findIndex 메서드는 자신을 호출한 배열의 요소를 순회하면서 인수로 전달된 콜백 함수를 호출하여 반환값이 true인 첫번째 요소의 인덱스를 반환한다.
  • true인 요소가 없다면 -1을 반환한다.
const user = [
  { id: 1, name: 'Lee' },
  { id: 2, name: 'Kim' },
  { id: 2, name: 'Choi' },
  { id: 3, name: 'Park' },
];

user.findIndex(user => user.id === 2); // 1
user.findIndex(user => user.name === 'Park'); // 3

27.9.10 Array.prototype.flatMap

  • flatMap 메서드는 map 메서드를 통해 생성된 새로운 배열을 평탄화한다.
  • 다만 평탄화 깊이를 지정할 수는 없고 1단계만 평탄화한다.
const arr = ['hello', 'world'];

arr.flatMap(x = > x.split(''));
// ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']

0개의 댓글