목차
배열이란?
•
배열 --> 여러 개의 값을 순차적으로 나열한 구조
•
사실 배열이라는 타입이 존재하는 것은 아니며 객체 타입임.
•
배열이 가지고 있는 값 : 요소(element) - javascript의 모든 값은 배열의 요소가 될 수 있음.
•
배열에서 자신의 위치를 나타내는 0 이상의 정수: 인덱스 --> 배열 접근시 대괄호 표기법을 이용해 인덱스를 지정하여 접근
•
배열의 길이를 나타내는 프로퍼티: length 프로퍼티
구분 | 객체 | 배열 |
구조 | 프로퍼티 키와 프로퍼티 값 | 인덱스와 요소 |
값의 참조 | 프로퍼티 키 | 인덱스 |
값의 순서 | X | O |
length 프로퍼티 | X | O |
값의 순서와 length 프로퍼티는 배열이 반복문을 통해 순차적으로 값에 접근하기 적합한 자료구조로 만들어줌
자바스크립트 배열은 배열이 아니다
•
밀집 배열 : 일반적인 자료구조에서 말하는 배열 --> 동일한 크기의 메모리 공간에 연속적으로 나열되어 있어서 offset으로 접근 가능
•
희소 배열 : 연속적으로 이어져 있지 않을 수 있는 배열 구조
JS 배열은 요소를 위한 각각의 메모리 공간이 동일한 크기를 갖지 않아도 되며,
일반적인 배열의 동작을 흉내 낸 특수한 객체
•
JS배열은 인덱스를 나타내는 문자열을 키로 가지면 length 프로퍼티를 가지는데 이는 일반 객체와 비슷해 보일 순 있지만 최신 JS 엔진은 배열을 이와 구별하여 최적화하여 구현하여 성능에서 약 2배 이상 차이
일반적인 배열과 JS 배열의 장단점
인덱스로 요소 접근시 | 특정 요소를 검색하거나 요소를 삽입, 삭제 시 | |
일반적인 배열 | 빠름 | 느림 (비효율적) |
JS 배열 | 느림 | 빠름 |
length 프로퍼티와 희소 배열
•
length 프로퍼티 : 요소의 개수
배열의 길이를 나타내는 0 이상의 정수를 값 소유 (0~ 2^32 -1 미만의 양수)
•
요소를 추가하거나 삭제할 때마다 자동 갱신
•
length에 명시적으로 값을 할당할 수 있는데 요소보다 작은 숫자 값을 할당하면 배열 길이가 줄어들고 큰 숫자를 할당하면 length프로퍼티 값이 변경되지만 길이는 고정.
(늘어난 곳은 콘솔로 보면 empty로 채워져있음, 메모리 공간도 확보하지 않음)
•
일반적인 배열의 length는 배열 요소의 개수(배열의 길이)와 일치
•
희소 배열은 length와 배열 요소의 개수가 일치하지 않고 희소 배열의 length가 실제 요소의 개수보다 언제나 큼.
•
희소 배열을 생성하지 않도록 주의하고, 배열에는 같은 타입의 요소를 연속적으로 위치시키는 것이 베스트
배열 생성
배열 리터럴
const arr = []; // [] 를 이용하여 생성
const arr2 = [1, , 3]; // 희소 배열
console.log(arr[1]); // undefined
TypeScript
복사
인덱스가 1인 요소에는 empty이며, undefined인 이유는 사실 arr에 프로퍼티 키가 '1'인 프로퍼티가 존재하지 않기 때문
Array 생성자 함수
•
Array 생성자 함수는 내부에서 new.target을 확인하기 때문에 new 연산자를 붙이지 않아도 배열을 생성하는 생성자 함수처럼 동작
•
인수가 없으면 빈 배열, 인수가 여러개이면 인수를 요소로 갖는 배열, 인수가 1개이면 그 인수만큼 length를 갖는 배열을 생성
•
요소를 2^32 -1 개 만큼 소유 가능
Array.of
•
ES6에서 도입된 메서드이며 전달된 인수를 요소로 갖는 배열을 생성
Array.of(1); // [1]
TypeScript
복사
Array.from
•
ES6에서 도입된 메서드이며 유사 배열 객체, 이터러블 객체를 인수로 전달받아 배열로 변환하여 반환
Array.from({length : 2, 0 : 'a', 1: 'b'}); // ['a', 'b']
// 콜백 함수를 통해 값을 만들면서 채우는 방법
Array.from({length: 3}, (_, i) => i); // [0, 1, 2]
TypeScript
복사
유사 배열 객체와 이터러블 객체
•
유사 배열 객체 : 배열처럼 인덱스로 프로퍼티 값에 접근할 수 있고 length 프로퍼티를 갖는 객체
•
for문으로 순회 가능
•
이터러블 객체 : Symbol.iterator 메서드를 구현하여 for...of문으로 순회 가능하고 스프레드 문법과 배열 디스트럭처링 할당의 대상으로 사용할 수 있는 객체
배열 요소의 참조
•
배열 요소를 참조할 때에는 대괄호 표기법( [ ] )을 사용하며 이 안에는 인덱스가 옴.
--> 객체의 프로퍼티 키와 같은 역할
•
존재하지 않는 요소에 접근 시 undefined가 반환
배열 요소의 추가와 갱신
•
존재하지 않는 인덱스를 사용해 값을 할당하면 새로운 요소가 추가
•
이때 length 프로퍼티 값은 자동 갱신 --> length 값보다 큰 인덱스로 새로운 요소 추가 시 희소배열이 됨.
const arr = [0];
// 배열 요소의 추가
arr[1] = 1;
console.log(arr); // [0, 1]
console.log(arr.length); // 2
arr[100] = 100;
console.log(arr); // [0, 1, empty × 98, 100] === 희소배열 (연속되지 않음)
console.log(arr.length); // 101
// 요소값의 갱신
arr[1] = 10;
console.log(arr); // [0, 10, empty × 98, 100]
// 명시적으로 값을 할당하지 않은 요소는 생성되지 않는다.
console.log(Object.getOwnPropertyDescriptors(arr));
/*
{
'0': {value: 0, writable: true, enumerable: true, configurable: true},
'1': {value: 1, writable: true, enumerable: true, configurable: true},
'100': {value: 100, writable: true, enumerable: true, configurable: true},
length: {value: 101, writable: true, enumerable: false, configurable: false}
*/
TypeScript
복사
•
정수 이외의 값을 인덱스 처럼 사용하면 프로퍼티가 생성되고 이는 length 값에 영향 X
const arr = [];
// 배열 요소의 추가
arr[0] = 1;
arr['1'] = 2;
// 프로퍼티 추가
arr['foo'] = 3;
arr.bar = 4;
arr[1.1] = 5;
arr[-1] = 6;
console.log(arr); // [1, 2, foo: 3, bar: 4, '1.1': 5, '-1': 6]
// 프로퍼티는 length에 영향을 주지 않는다.
console.log(arr.length); // 2
TypeScript
복사
배열 요소의 삭제
const arr = [1, 2, 3];
delete arr[1]; // 사용하지마셈
console.log(arr); // [1, empty, 3]
console.log(arr.length); // 3
// 밑에거 추천
// Array.prototype.splice(삭제를 시작할 인덱스, 삭제할 요소 수)
// arr[1]부터 1개의 요소를 제거
arr.splice(1, 1);
console.log(arr); // [1, 3]
// length 프로퍼티가 자동 갱신
console.log(arr.length); // 2
TypeScript
복사
배열은 사실 객체여서 delete 연산자를 사용 가능
BUT 이렇게 삭제하면 희소 배열이 되기 때문에 length 프로퍼티 값은 변하지 않아서 사용하지 않는 것이 좋음.
•
희소배열 안만들려면 delete 대신 splice메서드 사용 추천
배열 메서드
•
배열을 다룰 때 다양한 빌트인 메서드를 제공하는데 Array 생성자 함수는 정적 메서드를, 배열 객체의 프로토타입인 Array.prototype은 프로토타입 메서드를 제공
•
결과물을 반환하는 패턴
◦
원본 배열을 직접 변경하는 메서드(mutator method) : ex) push
◦
원본 배열을 직접 변경하지 않고 새로운 배열을 생성하여 반환하는 메서드(accessor method) : ex) concat
•
부수효과를 최소화하기 위해 원본 배열을 직접 변경하지 않는 메서드 사용 권장
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 })
TypeScript
복사
Array.prototype~
.indexOf
•
원본 배열에서 인수로 전달된 요소를 검색하여 인덱스 반환
array.indexof(searchItem: T, [startIndex: number])
TypeScript
복사
•
첫 번째 인수 : 검색할 요소
•
두 번째 인수 : 검색을 시작할 인덱스
◦
중복되는 요소가 여러개 있다면 처음 요소의 인덱스 반환
◦
없으면 -1 반환
.push (스프레드(…) 문법으로 대체) 부수효과有
array.push(...items: T)
TypeScript
복사
•
배열의 마지막 요소에 인수로 전달받은 모든 값을 추가하고 변경된 length값 반환
•
추가해야할 요소가 1개라면 arr[arr.length] = 인수; 이렇게 직접 추가하는 것이 더 성능적인 면에선 좋다.
•
push는 원본배열의 부수효과를 발생시켜서 스프레드 문법 사용 권장
const arr = [1, 2];
const newArr = [...arr, 3];
console.log(newArr); // [1, 2, 3]
//또는
arr[arr.length] = 3;
console.log(arr); // [1, 2, 3]
TypeScript
복사
.pop 부수효과有
array.pop()
TypeScript
복사
•
원본 배열에서 마지막 요소를 제거하고 제거한 요소 반환.
•
push와 pop ⇒ 스택 구현 가능
.unshift (스프레드(…) 문법으로 대체) 부수효과有
array.unshift(...items: T)
TypeScript
복사
•
원본 배열의 선두에 요소로 인수를 추가하고 push처럼 변경된 length 값을 반환
.shift 부수효과有
array.shift()
TypeScript
복사
•
원본 배열에서 첫 번째 요소를 제거하고 제거한 요소를 반환
•
빈 배열이면 undefined 반환
•
shift와 push ⇒ queue 구현 가능
.concat (스프레드(…) 문법으로 대체) 부수효과有
•
인수로 전달된 값들을 원본 배열의 마지막 요소로 추가한 새로운 배열을 반환
•
push, unshift와 concat의 차이점
◦
새로운 배열을 반환하는 것 -> 반환 값을 반드시 변수에 할당 받아야 한다.
◦
인수로 전달받은 것이 배열인 경우 push와 unshift는 그대로 요소를 추가하지만 concat 메서드는 배열을 해체하여 새로운 배열의 마지막 요소로 추가
•
ES6의 스프레드 문법으로 대체 가능 <-- 스프레드 문법을 일관성 있게 사용 권장
.splice 부수효과有
•
원본배열 직접 변경
splice(startIndex: number, deleteCount: number, items: T);
TypeScript
복사
•
start: 원본 배열 요소를 제거하기 시작할 인덱스, -1이면 마지막 요소를 가리킴
•
deleteCount: 원본 배열 요소를 제거하기 시작할 인덱스인 start 부터 제거할 요소, 0이면 아무것도 제거되지 않는다. --> start 부터 모든 요소 제거됨
•
items: 제거한 위치에 삽입할 요소들의 목록
.slice 부수효과無
•
원본 배열 변경 X
slice(startIndex: number, endIndex: number);
TypeScript
복사
•
start: 복사를 시작할 인덱스이며 음수인 경우 배열의 끝에서의 인덱스를 나타냄
•
end: 복사를 종료할 인덱스이며 생략 시 기본값은 length 프로퍼티 값
•
모든 인수 생략시 원본 배열의 복사본을 생성해서 반환(얕은 복사)
•
arguments(유사배열 객체이면서 이터러블 객체)와 같은 유사 배열 객체를 배열로 변환하는 방법
◦
.slice.call(arguments); // slice 사용
◦
Array.from(arguments); // Array.from 사용
◦
[...arguments]; // 스프레드 연산자 사용(이터러블 객체는 스프레드 문법 사용가능)
.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'
TypeScript
복사
•
원본 배열의 모든 요소를 문자열로 변환한 후, 인수로 전달받은 문자열로 연결한 문자열을 반환
인수 생략 시 기본 구분자는 콤마(,)
.reverse 부수효과有
const arr = [1, 2, 3];
const result = arr.reverse();
// reverse 메서드는 원본 배열을 직접 변경
console.log(arr); // [3, 2, 1]
// 반환값은 변경된 배열이다.
console.log(result); // [3, 2, 1]
TypeScript
복사
•
원본 배열의 순서를 반전
•
반환 값은 변경된 배열
.fill 부수효과有
const arr = [1, 2, 3];
// 인수로 전달받은 값 0을 배열의 인덱스 1부터 끝까지 요소로 채움
arr.fill(0, 1);
// fill 메서드는 원본 배열을 직접 변경
console.log(arr); // [1, 0, 0]
TypeScript
복사
•
인수로 전달받은 값을 배열의 처음부터 끝까지 요소로 보충. (원본 배열 직접 변경)
•
두 번째 인수는 시작할 인덱스, 세 번째 인수는 종료할 인덱스
.includes 부수효과無
const arr = [1, 2, 3];
// 배열에 요소 2가 포함되어 있는지 확인한다.
arr.includes(2); // -> true
// 배열에 요소 100이 포함되어 있는지 확인한다.
arr.includes(100); // -> false
TypeScript
복사
•
ES7에서 도입된 메서드이며 특정 요소가 있는지 확인하여 true 또는 false를 반환
•
두 번째 인수로 시작할 인덱스 전달 가능(음수 전달 시 length 프로퍼티 값과 합산하여 검색 시작 인덱스 설정)
•
indexOf와 차이점은 indexOf는 NaN이 포함되어있는지 확인할 수 없지만 includes는 가능
.flat 부수효과有
•
ES10에서 도입된 메서드로 인수로 전달한 깊이만큼 재귀적으로 배열을 평탄화
•
인수를 생략한 경우 기본값은 1이고, Infinity 전달 시 중첩 배열 모두를 평탄화
배열 고차 함수
•
고차함수 : 함수를 인수로 전달받거나 함수를 반환하는 함수
--> 외부 상태의 변경이나 가변 데이터를 피하고 불변성을 지향하는 함수형 프로그래밍에 기반
함수형 프로그래밍
•
조건문과 반복문을 제거하여 복잡성을 해결하고 변수의 사용을 억제하여 상태변경을 피함.
•
순수 함수를 통해 부수효과를 최대한 억제
.sort 부수효과有
// 오름차순(ascending) 정렬
fruits.sort();
TypeScript
복사
•
sort 배열의 요소를 정렬한다. 기본적으로 오름차순으로 정렬(영어)
•
유니코드 코드 포인트의 순서를 따라 정렬하기 때문에 숫자는 정렬 순서를 정의하는 비교 함수를 인수로 전달해야함
•
sort메서드의 정렬 알고리즘은 quicksort를 사용하다가 동일한 값의 요소가 중복되어 있을 때, 초기 순서와 변경 될 수 있어서 ES10부터는 timsort 알고리즘을 사용
.forEach 부수효과無
•
for문 대체 고차함수
•
배열의 모든 요소를 순회하며 콜백함수를 반복 호출
[1, 2, 3].forEach((item, index, arr) => {
console.log(...); });
TypeScript
복사
요소값, 인덱스, this의 인수를 전달하며 여기서 this는 호출한 배열을 의미
이 this를 통해 원본 배열을 변경 가능
forEach((item.index,arr) => {arr[index] = item * 2; }); 와 같은 방법으로 원본배열 변경 가능
const numbers = [1, 2, 3];
let pows = [];
// forEach 메서드는 numbers 배열의 모든 요소를 순회하면서 콜백 함수를 반복 호출
numbers.forEach(item => pows.push(item ** 2));
console.log(pows); // [1, 4, 9]
TypeScript
복사
•
forEach 메서드의 반환값은 언제나 undefined
•
이 메서드의 두 번째 인수로 콜백함수 내부에서 this로 사용할 객체를 전달 가능
--> 그냥 화살표 함수 사용이 젤 편함
•
forEach 메서드는 break, continue 문을 사용할 수 없고, 희소 배열의 경우 존재하지 않는 요소는 순회대상에서 제외
•
for문 보다 성능이 좋지는 않지만 가독성이 더 좋아서 높은 성능이 필요한 경우가 아니라면 이를 사용 권장
.map 부수효과無
•
콜백 함수의 반환값들로 구성된 새로운 배열을 반환
•
map 메서드가 생성하여 반환하는 새로운 배열의 length 프로퍼티 값은 map 메서드를 호출한 배열의 length 프로퍼티 값과 반드시 일치한다. 즉 map 메서드를 호출한 배열과 map 메서드가 생성하여 반환한 배열은 1:1 매핑한다.
•
forEach와 마찬가지로 요소값, 인덱스, this의 인수를 전달 할 수 있다.
•
두 번째 인수로 콜백함수 내부에서 this로 사용할 객체 전달 가능
.filter 부수효과無
array.filter(callback)
TypeScript
복사
•
콜백 함수의 반환 값이 true인 요소로만 구성된 새로운 배열 반환
•
filter 메서드가 생성하여 반환한 새로운 배열의 length 프로퍼티 값은 filter 메서드를 호출한 배열의 length 프로퍼티 값과 같거나 작다.
•
요소값, 인덱스, this 순차적 전달, 콜백 함수 내부에서 this로 사용할 객체 전달가능
•
filter 메서드를 사용해 자신을 호출한 배열에서 특정 요소를 제거하기 위해 사용 가능
const numbers = [1, 2, 3, 4, 5];
// filter 메서드는 numbers 배열의 모든 요소를 순회하면서 콜백 함수를 반복 호출
// 그리고 콜백 함수의 반환값이 true인 요소로만 구성된 새로운 배열을 반환한
// 다음의 경우 numbers 배열에서 홀수인 요소만을 필터링(1은 true로 평가).
const odds = numbers.filter(item => item % 2);
console.log(odds); // [1, 3, 5]
// filter 메서드는 콜백 함수를 호출하면서 3개(요소값, 인덱스, this)의 인수를 전달
[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]
*/
TypeScript
복사
.reduce 부수효과無
arr.reduce(callback[, initialValue])
JavaScript
복사
•
callback : 배열의 각 요소에 대해 실행할 함수. 다음 네 가지 인수를 가짐
◦
accumulator : 누산기. 콜백의 반환값을 누적. 콜백의 이전 반환값 또는, 콜백의 첫 번째 호출이면서 initialValue를 제공한 경우에는 initialValue의 값임
◦
currentValue : 처리할 현재 요소
◦
currentIndex (Optional) : 처리할 현재 요소(currentValue)의 인덱스. initialValue를 제공한 경우 0, 아니면 1부터 시작
◦
array (Optional) : reduce()를 호출한 배열
•
자신을 호출한 배열의 모든 요소를 순회하며 인수로 전달받은 콜백 함수를 반복호출
•
그러면서 콜백 함수의 반환값을 다음 순회시에 콜백함수의 첫 번째 인자로 전달하면서 함수를 호출하여 하나의 결과 값을 만들어 반환
const sum = [1,2,3,4].reduce((accumulator, currentValue, index, array) => accumulator + currentValue, 0);
console.log(sum); // 10
const values = [1, 2, 3, 4, 5, 6];
const average = values.reduce((acc, cur, i, { length }) => {
// 마지막 순회가 아니면 누적값을 반환하고 마지막 순회면 누적값으로 평균을 구해 반환
return i === length - 1 ? (acc + cur) / length : acc + cur;
}, 0);
console.log(average); // 3.5
const values = [1, 2, 3, 4, 5];
const max = values.reduce((acc, cur) => (acc > cur ? acc : cur), 0);
console.log(max); // 5
TypeScript
복사
•
reduce 메서드의 다양한 활용법
◦
평균 구하기
◦
최대값 구하기 --> Math.max가 더 직관적
◦
요소의 중복 횟수 구하기
◦
중첩 배열 평탄화 --> flat 메서드가 더 직관적
◦
중복 요소 제거 ---> filter나 Set이 더 직관적
•
reduce 메서드의 두 번째 인수로 전달하는 초기값은 옵션인데 언제나 초기값을 전달하는 것이 안전 (객체의 특정 프로퍼티 값을 합산하는 경우에는 반드시 초기값 전달해주어야 함)
.some
•
자신을 호출한 배열의 요소를 순회하면서 인수로 전달된 콜백 함수를 호출
•
반환값이 단 한번이라도 참이면 true, 모두 거짓이면 false를 반환
[5, 10, 15].some(item => item > 10) // -> true
// some 메서드를 호출한 배열이 빈 배열인 경우 항상 false 반환
[].some(item => item > 3) // -> false
TypeScript
복사
.every
•
자신을 호출한 배열의 요소를 순회하면서 인수로 전달된 콜백 함수 호출
•
반환값이 모두 참이면 true, 단 한번이라도 거짓이면 false 반환
[5, 10, 15].every(item => item > 3) // -> true
// every메서드를 호출한 배열이 빈 배열인 경우 항상 true 반환
[].every(item => item > 3) // -> true
TypeScript
복사
.find
arr.find(callback(element, index, array), thisArg)
JavaScript
복사
•
arr : 순회하고자 하는 배열
◦
element : 현재 배열의 요소
◦
index(생략 가능) : 현재 배열 요소의 index
◦
array(생략 가능) : filter 함수를 호출한 배열
◦
thisArg(생략 가능) : callback을 실행할 때 this로 사용되는 값(= map 함수에서 사용될 this값)
•
자신을 호출한 배열의 요소를 순회하면서 인수로 전달된 콜백 함수를 호출하여 반환 값이 true인 첫 번째 요소를 반환
•
조건에 일치하는 배열 요소가 없을 경우 undefined 반환
•
결과 값이 배열이 아닌 요소값
// Array#filter는 배열을 반환한다.
[1, 2, 2, 3].filter(item => item === 2); // -> [2, 2]
// Array#find는 요소를 반환한다.
[1, 2, 2, 3].find(item => item === 2); // -> 2
TypeScript
복사
.findIndex
arr.findIndex(callback(element, index, array), thisArg)
arr.findIndex((arrItem) => arrItem.item === condition)
JavaScript
복사
•
arr : 순회하고자 하는 배열
◦
element : 현재 배열의 요소
◦
index(생략 가능) : 현재 배열 요소의 index
◦
array(생략 가능) : filter 함수를 호출한 배열
◦
thisArg(생략 가능) : callback을 실행할 때 this로 사용되는 값(= map 함수에서 사용될 this값)
•
ES6에 도입된 메서드로 반환값이 true 인 첫번째 요소의 인덱스 반환
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
// 위와 같이 프로퍼티 키와 프로퍼티 값으로 요소의 인덱스를 구하는 경우
// 다음과 같이 콜백 함수를 추상화 가능
function predicate(key, value) {
// key와 value를 기억하는 클로저를 반환
return item => item[key] === value;
}
// id가 2인 요소의 인덱스를 구한다.
users.findIndex(predicate('id', 2)); // -> 1
// name이 'Park'인 요소의 인덱스를 구한다.
users.findIndex(predicate('name', 'Park')); // -> 3
TypeScript
복사
.flatMap
•
ES10에서 도입된 메서드로 map 메서드를 통해 생성된 새로운 배열 평탄화
•
map 메서드와 flat 메서드를 순차적으로 실행하는 효과
•
1단계만 평탄화 할 수 있으므로 깊이를 지정해야 한다면 flatMap 메서드 대신 map 메서드와 flat 메서드를 각각 호출