모자딥 27장 배열

릿·2023년 2월 5일
0

27장 배열

27.1 배열이란?


  • 여러 개의 값을 순차적으로 나열한 자료구조
  • 요소: 배열이 가지고 있는 값
  • 인덱스 : 배열에서 자신의 위치를 나타내는 0 이상의 정수
  • length프로퍼티 : 배열의 길이를 나타냄

배열과 일반 객체의 차이

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


  • 자바스크립트의 배열은 동일한 크기를 갖지 않아도 되며 연속적으로 이어져있지 않을수도 있는데 이를 희소 배열이라고 함
  • 자바스크립트의 배열은 일반적인 배열의 동작을 나타낸ㄴ 특수한 객체임

1. 일반 배열과 자바스크립트 배열의 장단점

  • 일반 배열은 인덱스로 요소에 빠르게 접근할 수 있는 장점이 있고, 요소를 삽입, 삭제하는 경우에는 효율적이지 않다는 단점이 있음
  • 자바스크립트 배열은 해시 테이블로 구현된 객체이므로 인덱스로 요소에 접근하는 경우, 일반적인 배열보다 성능적인 면에서 느릴 수 밖에 없는 구조적인 단점이 있고, 요소를 삽입 또는 삭제하는 경우에는 일반적인 배열보다 빠른 성능을 기대할 수 있다는 장점이 있음

27.3 length프로퍼티와 희소 배열


  • length프로퍼티는 배열의 길이를 나타내는 0이상의 정수를 값으로 가짐
  • 희소배열은 length는 희소 배열의 실제 요소 개수보다 언제나 크므로 배열을 생성할 때 희소 배열을 생성하지 않도록 주의할 것

27.4 배열 생성


27.4.1 배열 리터럴

  • 일반적인 배열 리터럴
const arr = [1, 2, 3];
  • 배열 리터럴에 요소를 생략하면 희소 배열이 생성됨
const arr = [1, , 3]

27.4.2 Array 생성자 함수

Array 생성자 함수의 특징

  • 전달된 인수가 1개이고 숫자인 경우, length프로퍼티 값이 인수인 배열을 생성함 (이 때 생성된 배열은 희소 배열임)
const arr = new Array(10);
  • 전달된 인수가 없는 경우 빈 배열을 생성함
new Array(); // -> []
  • 전달된 인수가 2개 이상이거나 숫자가 아닌 경우 인수를 요소로 갖는 배열을 생성함
new Array(1, 2, 3); // -> [1, 2, 3]
new Array({}); // -> [{}]

27.4.3 Array.of (ES6)

  • Array.of메서드는 전달된 인수를 요소로 갖는 배열을 생성함
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']

27.5 배열 요소의 참조


  • 배열 요소를 참조할 떄는 대괄호 표기법을 사용하여 대괄호 안에 인덱스를 넣어줌
  • 존재하지 않는 요소에 접근하면 undefined가 반환됨
const arr = [1, 2];

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

27.6 배열 요소의 추가와 갱신


  • 배열은 요소를 동적으로 추가할 수 있음, 존재하지 않은 인덱스 값을 사용해 할당하면 새로운 요소가 추가되고, length프로퍼티 값은 자동으로 갱신됨
const arr = [0];

arr[1] = 1;

console.log(arr); // [0, 1]
console.log(arr.length); // 2
  • 현재 배열의 length프로퍼티 값보다 큰 인덱스를 새로운 요소로 추가하면 희소배열이 됨
  • 이미 요소가 존재하는 요소에 값을 재할당하면 요소값이 갱신됨
arr[100] = 100;

console.log(arr); // [0, 1, empty * 98, 100]
console.log(arr.length); // 101

27.7 배열 요소의 삭제


  • 배열의 특정 요소를 삭제하기 위해 delete연산자를 사용할 수 있음
const arr = [1, 2, 3];

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

// length프로퍼티에 영향을 주지 않음, 즉 희소 배열이 됨
console.log(arr.length); // 3
  • 희소배열을 만들지 않으면서 배열의 특정 요소를 완전히 삭제하려면 Array.prototype.splice메서드를 사용함
const arr = [1, 2, 3];

// Array.prototype.splice(삭제를 시작한 인덱스, 삭제할 요소 수)
// arr[1]부터 1개의 요소를 제거
arr.splice(1, 1);
console.log(arr); // [1, 3]

// length 프로퍼티가 자동 갱신됨
console.log(arr.length); // 2

27.8 배열 메서드


  • 원본 배열을 직접 변경하는 메서드
  • 원본 배열을 직접 변경하지 않고 새로운 배열을 생성하여 반환하는 메서드

27.8.1 Array.isArray

  • Array생성자 함수의 정적메서드로, 인수가 배열이면 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
  • indexOf메서드 대신 ES7에서 도입된 Array.prototype.includes메서드를 사용하면 가독성이 더 좋음
const foods = ['apple', 'banana', 'orange'];

if (!foods.includes('orange')) {
  foods.push('orange');
}

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

27.8.3 Array.prototype.push

  • push메서드는 인수로 전달받은 모든 값을 원본 배열의 마지막 요소로 추가하고 변경된 length 프로퍼티 값을 반환함 (push메서드는 원본 배열을 직접 변경함)
const arr = [1, 2];

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

// push 메서드는 원본 배열을 직접 변경한다.
console.log(arr); // [1, 2, 3, 4]
  • push메서드는 성능면에서 좋지 않음. 마지막 요소로 추가할 요소가 하나 뿐이날면 아래와 같은 방법이 빠름
const arr = [1, 2];

arr[arr.length] = 3;
console.log(arr); // [1, 2, 3]
  • push메서드는 원본 배열을 직접 변경하는 부수 효과가 있으므로 ES6의 스프레드 문법을 사용하는 편이 좋음
const arr = [1, 2];

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

27.8.4 Array.prototype.pop

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

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

// pop메서드는 원본 배열을 직접 변경함
console.log(arr); // [1]
  • pop메서드와 push메서드를 사용하면 스택을 쉽게 구현할 수 있음

27.8.5 Array.prototype.unshift

  • unshift메서드는 인수로 전달받은 모든 값을 원본 배열의 선두에 요소로 추가하고 변경된 length프로퍼티 값을 반환함, 원본 배열을 직접 변경함
const arr = [1, 2];

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

// unshift 메서드는 원본 배열을 직접 변경함
console.log(arr); // [3, 4, 1, 2]
  • unshift메서드는 원본 배열을 변경하는 부수효과가 있으므로 ES6 스프레드 문법을 사용하는 편이 좋음
const arr = [1, 2];

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

27.8.6 Array.prototype.shift

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

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

// shift메서드는 원본 배열을 직접 변경함
console.log(arr); // [2]
  • shift메서드와 push메서드를 사용하면 큐를 쉽게 구현할 수 있음

27.8.7 Array.prototype.concat

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

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]

push메서드, unshift메서드와 concat메서드의 차이점

  1. 원본 배열 변경여부
  • push, unshift메서드 : 원본 배열 직접 변경, 원본 배열을 반드시 변수에 저장해두어야 함
  • concat: 새로운 배열 반환, 반환값을 반드시 변수에 할당받아야 함
  1. 인수로 전달받은 값이 배열인 경우
  • push, unshift: 배열을 그대로 원본 배열의 마지막/첫번째 요소로 추가
  • concat: 인수로 전달받은 배열을 해체하여 새로운 배열의 마지막 요소로 추가

결론

  • concat메서드는 ES6스프레드 문법으로 대체할 수 있으므로 push, unshift, concat메서드를 쓰는 것 보다 일관성 있게 ES6스프레드 문법 사용을 권장함

27.8.8 Array.prototype.splice

  • splice메서드는 원본 배열의 중간에 요소를 추가하거나 중간에 있는 요소를 제거하는 경우 사용, 원본 배열이 변경됨

매개변수 설명

  • start: 원본 배열의 요소를 제거하기 시작할 인덱스, start를 지정하면 원본배열의 start부터 모든 요소를 제거, start가 음수일 경우, 배열의 끝에서의 인덱스를 나타냄
  • deleteCount: 원본 배열의 요소를 제거하기 시작할 인덱스인 start부터 제거할 요소의 개수, deleteCount가 0인 경우, 아무런 요소가 제거되지 않음 (옵션)
  • items: 제거한 위치에 삽입할 요소들의 목록, 생략할 경우 원본 배열에서 요소를 제거하기만 함 (옵션)
const arr = [1, 2, 3, 4];

const result = arr.splice(1, 2, 20, 30);

console.log(result): // [2, 3]

// splice메서드는 원본 배열을 직접 변경함
console.log(arr); // [1, 20, 30, 4]
  • 배열에서 특정 요소를 제거하려면 indexOf메서드를 통해 특정 요소의 인덱스를 취득한 다음, splice메서드를 사용함
const arr = [1, 2, 3, 4, 5];

function remove(array, item) {
  const index = array.indexOf(item);
  
  if (index !== -1) array.splice(index, i);
  
  return array;
}

console.log(remove(arr, 2)); // [1, 3, 1, 2]
console.log(remove(arr, 10)); // [1, 3, 1, 2]
  • filter메서드를 사용하여 특정 요소를 제거할 수도 있는데 이 경우 특정 요소가 중복된 경우 모두 제거됨
const arr = [1, 2, 3, 1, 2];

// 배열 array에서 모든 item요소를 제거함
function removeAll(array, item) {
  return array.filter(v => v !== item);
}

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

27.8.9 Array.prototype.slice

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

매개변수 설명

  • start: 복사를 시작할 인덱스, 음수인 경우 배열의 끝에서의 인덱스를 나타냄
  • end: 복사를 종료할 인덱스, 이 인덱스에 해당하는 요소는 복사되지 않음, end는 생략이 가능하며 생략시 기본값은 length프로퍼티 값임
const arr = [1, 2, 3];

arr.slice(0, 1); // [1]
arr.slice(1, 2); // [2]

// 원본은 변경되지 않음
console.log(arr); // [1, 2, 3]
  • 인수를 모두 생략하면 원본 배열의 복사본을 생성해서 반환함
  • slice메서드로 유사배열객체를 배열로 변환할 수 있으나 Array.from메서드를 사용하는 것이 더욱 간단함

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();

// 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];

arr.fill(0);
console.log(arr); // [0, 0, 0]
  • 두번째 인수로 요소 채우기를 시작한 인덱스를 전달할 수 있음
const arr = [1, 2, 3];

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

// fill메서드는 원본 배열을 직접 변경
console.log(arr); // [1, 0, 0]
  • 세번쨰 인수로 요소 채우기를 멈출 인덱스를 전달할 수 있음
const arr = [1, 2, 3, 4, 5];

arr.fill(0, 1, 3);
console.log(arr); // [1, 0, 0, 4, 5]
  • fill메서드를 사용하면 배열을 생성하면서 특정 값으로 요소를 채울 수 있음, 하지만 모든 요소를 하나의 값으로만 채울 수 밖에 없다는 단점이 있음
const arr = new Array(3);
console.log(arr); // [empty * 3]

const retult = arr.fill(1);

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

27.8.13 Array.prototype.includes (ES7)

  • includes메서드는 배열 내에 특정 요소가 포함되어 있는지 확인하여 true, false를 반환함
  • 첫번째 인수로 검색할 대상을 지정함
  • 두번째 인수로 검색을 시작할 인덱스를 전달할 수 있고, 두번째 인수를 생략할 경우 기본값 0이 설정, 음수를 전달하면 length프로퍼티 값과 음수 인덱스를 합산하여 (length + index) 검색 시작 인덱스를 설정함
const arr = [1, 2, 3];

arr.includes(2);
arr.includes(100);

// 배열에 요소 1이 포함되어 있는지 인덱스 1부터 확인함
arr.includes(1, 1); // -> false
// 배열에 요소 3이 포함되어 있는지 인덱스 2(arr.length -1)부터 확인함
arr.includes(3, -1); // -> true
  • indexOf메서드를 사용해도 되지만 반환값이 -1인지, 배열에 NaN이 포함되어 있는지 확인할 수 없다는 문제가 있음
[NaN].indexOf(NaN) !== -1; // -> false
[NaN].includes(NaN); // -> true

27.8.14 Array.prototype.flat (ES10)

  • flat메서드는 인수로 전달한 깊이만큼 재귀적으로 배열을 평탄화함
  • 중첩 배열을 평탄화할 깊이를 인수로 전달할 수 있고, 생략할 경우 기본값 1이 적용됨, 인수로 Infinity를 전달하면 중첩 배열 모두를 평탄화 함
[1, [2, 3, 4, 5]].flat(); // [1, 2, 3, 4, 5]
[1, [2, [3, [4]]]].flat(1); // [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'];

fruits.sort();

console.log(fruits); // ['Apple', 'Banana', 'Orange']
  • 한글 문자열인 요소도 오름차순으로 정렬됨
const fruits = ['바나나', '오렌지', '사과'];

fruits.sort();

console.log(fruits); // ['바나나', '사과', '오렌지']
  • 내림차순으로 정렬하려면 sort메서드를 사용하여 오름차순 정렬 후, reverse메서드를 사용하여 순서를 뒤집음
const fruit = ['Banana', 'Orange', 'Apple'];

fruits.sort();

console.log(fruits); ['Apple', 'Banana', 'Orange']

fruits.reverse();

console.log(fruits); // ['Orange', 'Banana', 'Apple']
  • 숫자요소로 정렬할 떄는 sort메서드에 정렬 순서를 정의하는 비교함수를 인수로 전달해야 함
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]
  • 객체를 요소로 갖는 배열을 정렬하는 예제는 아래와 같음
const todos = [
  { id: 4, content: 'javascript' },
  { id: 1, content: 'HTML' },
  { id: 2, content: 'CSS' },  
]

function compare(key) {
  // 프로퍼티 값이 문자열인 경우 - 산술 연산으로 비교하면 NaN이 나오므로 비교 연산을 사용함
  // 비교 함수는 양수/음수/0을 반호나하면 되므로 - 단술 연산 대신 비교 연산을 사용할 수 있음
  return (a, b) => (a[key] > b[key] ? 1 : (a[key] < b [key] ? -1 : 0));
}

// id를 기준으로 오름차순 정렬
todos.sort(compare('id'));

// content를 기준으로 오름차순 정렬
todos.sort(compare('content'))

27.9.2 Array.prototype.forEach

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

// for문으로 배열 순회
for (let i=0; i<numbers.length; i++) {
  pows.push(numbers[i] ** 2);
}
console.log(pows); // [1, 4, 9]

// forEach메서드는 numbers 배열의 모든 요소를 순회하면서 콜백 함수를 반복 호출함
numbers.forEach(item => pows.push(item ** 2));
console.log(pows); // [1, 4, 9]
  • forEach메서드는 콜백 함수를 호출할 때 메서드 호출한 배열의 요소값과 인덱스, forEach메서드를 호출한 배열(this)를 순차적으로 전달함
// forEach메서드는 콜백 함수를 호출하면서 3개(요소값, 인덱스, this)의 인수를 전달함
[1, 2, 3].forEach((item, index, arr) => {
  console.log(`요소값: ${item}, 인덱스: ${index}, this: ${JSON.stringify(arr)}`);
})
  • forEach메서드는 원본 배열을 변경하지 않음, 하지만 콜백함수를 통해 원본 배열을 변경할 수 있음
const numbers = [1, 2, 3];

numbers.forEach((item, index, arr) => { arr[index] = item ** 2; });
console.log(numbers); // [1, 4, 9]
  • forEach메서드의 반환값은 언제나 undefined임
  • forEach메서드는 break, continue문을 사용할 수 없음
  • 희소배열의 경우, 존재하지 않는 요소는 순회 대상에서 제외됨
  • forEach메서드는 for문에 비해 성능은 좋지 않지만 가독성은 더 좋음

27.9.3 Array.prototype.map

  • map메서드는 자신이 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백함수를 반복호출함
  • 콜백 함수의 반환값들로 구성된 새로운 배열을 반환함
  • 원본 배열은 변경되지 않음
  • 매개변수로 map메서드를 호출한 배열의 요소값과 인덱스, map메서드를 호출한 배열(this)를 순차적으로 전달함
const numbers = [1, 4, 9];

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

[1, 2, 3].map((item, index, arr) => {
  console.log(`요소값: ${item}, 인덱스: ${index}, this: ${JSON.stringify(arr)}`);
  return item;
});

27.9.4 Array.prototype.filter

  • filter메서드는 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백 함수를 반복 호출함
  • 콜백 함수의 반환값이 true인 요소로만 구성된 새로운 배열을 반환함
  • 원본 배열은 변경되지 않음
  • 매개변수로 filter메서드를 호출한 배열의 요소값과 인덱스, filter메서드를 호출한 배열(this)를 순차적으로 전달함
const numbers = [1, 2, 3, 4, 5];

const odds = numbers.filter(item => item % 2);
console.log(odds); // [1, 3, 5]

[1, 2, 3].filter((item, index, arr) => {
  console.log(`요소값: ${item}, 인덱스: ${index}, this: ${JSON.stringify(arr)}`);
  return item % 2;
});
  • filter메서드는 자신을 호출한 배열에서 특정 요소를 제거하기 위해 사용할 수 있음
class Users {
  constructor() {
    this.users = [
      { id: 1, name: 'Lee' },
      { id: 2, name: 'Kim' }
    ];
  }
  
  // 요소 추출
  findById(id) {
    // id가 일치하는 사용자만 반환한다.
    return this.users.filter(user => user.id === id);
  }    
  // 요소 제거
  remove(id) {
    // id가 일치하지 않는 사용자를 제거한다.
    this.users = this.users.filter(user => user.id !== id);
  }
}

const users = new Users();

let user = users.findById(1);
console.log(user); // [{ id: 1, name: 'Lee' }]

// id가 1인 사용자를 제거한다.
users.remove(1);

user = users.findById(1);
console.log(user); // []
  • filter메서드를 사용하면 중복된 요소가 전부 제거되기 때문에 특정 요소를 하나만 제거하려면 index메서드 + splice메서드 조합을 사용함

27.9.5 Array.prototype.reduce

  • reduce메서드는 자신을 호출한 배열을 모든 요소를 순회하며 인수로 전달받은 콜백 함수를 반복 호출하고, 하나의 결과값을 만들어 반환함
  • 원본 배열은 변경되지 않음
  • 매개변수는 콜백함수의 4개 인수(초기값 또는 콜백 함수의 이전 반환값, reduce메서드를 호출한 배열의 요소값, 인덱스, reduce메서드를 호출한 배열 자체), 초기값(생략가능)을 전달받음
// 1부터 4까지 누적을 구한다
const sum = [1, 2, 3, 4].reduce((accumulator, currentValue, index, array) => accumulator + currentValue, 0);

console.log(sum); // 10
  • 평균구하기, 최대값 구하기(Math.max를 쓰는 편이 나음), 요소의 중복 횟수 구하기, 중첩 배열 평탄화(flat메서드를 쓰는 편이 나음), 중복요소 제거(filter메서드, Set을 쓰는 편이 나음)
  • 객체의 특정 프로퍼티 값을 합산하는 경우에는 초기값을 반드시 전달해야 함

27.9.6 Array.prototype.some

  • some메서드는 배열의 요소중에 콜백함수를 통해 정의한 조건을 만족하는 요소가 1개 이상 존재하는지 확인하여 그 결과를 true/false로 반환함
  • 단, 호출한 배열이 빈 배열일 경우, 항상 false를 반환함
  • some메서드 콜백함수는 some메서드를 호출한 요소값, 인덱스, some메서드를 호출한 배열 자체를 전달받을 수 있음
[5, 10, 15].some(item => item > 10); // true

27.9.7 Array.prototype.every

  • every메서드는 배열의 모든 요소가 콜백 함수를 통해 정의한 조건을 모두 만족하는지 확인하여 그 결과를 true/false로 반환함
  • 단, 호출한 배열이 빈 배열일 경우, 항상 false를 반환함
  • every메서드 콜백함수는 evert메서드를 호출한 요소값, 인덱스, every메서드를 호출한 배열 자체를 순차적으로 전달받을 수 있음
[5, 10, 15].every(item => item > 3); // -> true

27.9.8 Array.prototype.find (ES6)

  • find메서드는 자신이 호출한 배열의 요소를 순회하면서 인수로 전달된 콜백 함수를 호출하여 반환 값이 true인 첫번째 요소를 반환함, true인 요소가 존재하지 않는다면 undefined를 반환함
  • find 콜백함수는 find메서드를 호출한 요소값, 인덱스, find메서드를 호출한 배열 자체를 순차적으로 전달받을 수 있음
const users = [
  { id: 1, name: 'Lee' },
  { id: 2, name: 'Kim' },
  { id: 2, name: 'Choi' },
  { id: 3, name: 'Park'}
];

// id가 2인 첫번째 요소를 반환함. find메서드는 배열이 아니라 요소를 반환함
users.find(user => user.id === 2); // -> { id: 2, name: 'Kim' }

27.9.9 Array.prototype.findIndex (ES6)

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

// id가 2인 요소의 인덱스를 구한다.
users.findIndex(user => user.id === 2); // -> 1

// name이 'Park'인 요소의 인덱스를 구한다.
users.findIndex(user => user.name === 'Park'); // -> 3

27.9.10 Array.prototype.flatMap (ES10)

  • flat메서드는 map메서드를 통해 생성된 새로운 배열을 평탄화 함(map메서드 + flat메서드를 순차적으로 실행하는 효과), 단 평탄화 깊이는 지정할 수 없고 1단계만 평탄화 함
const arr = ['hello', 'world'];

// map과 flat을 순차적으로 실행
arr.map(x => x.split('')).flat();
// -> ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']

// flatMap은 map을 통해 생성된 새로운 배열을 평탄화함
arr.flatMap(x => x.split(''));
// -> ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']
profile
항상 재밌는 뭔가를 찾고 있는 프론트엔드 개발자

0개의 댓글