πŸ“ 27.1 λ°°μ—΄μ΄λž€?

λ°°μ—΄(array)은 μ—¬λŸ¬ 개의 값을 순차적으둜 λ‚˜μ—΄ν•œ μžλ£Œκ΅¬μ‘°λ‹€. 배열이 가지고 μžˆλŠ” 값을 μš”μ†Œ(element)라고 λΆ€λ₯΄κ³  μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ λͺ¨λ“  값은 λ°°μ—΄μ˜ μš”μ†Œκ°€ 될 수 μžˆλ‹€. λ°°μ—΄μ˜ μš”μ†ŒλŠ” 인덱슀(index)λ₯Ό 가지며 배열은 μš”μ†Œμ˜ 개수 즉, λ°°μ—΄μ˜ 길이λ₯Ό λ‚˜νƒ€λ‚΄λŠ” length ν”„λ‘œνΌν‹°λ₯Ό κ°–λŠ”λ‹€.

const arr = ['apple', 'banana', 'orange'];

arr.length // -> 3

μžλ°”μŠ€ν¬λ¦½νŠΈμ— λ°°μ—΄μ΄λΌλŠ” νƒ€μž…μ€ μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”λ‹€. 배열은 객체 νƒ€μž…μ΄λ‹€.

배열은 λ°°μ—΄ λ¦¬ν„°λŸ΄, Array μƒμ„±μž ν•¨μˆ˜, Array.of, Array.from λ©”μ„œλ“œλ‘œ 생성할 수 μžˆλ‹€. λ°°μ—΄μ˜ μƒμ„±μž ν•¨μˆ˜λŠ” Array 이며, λ°°μ—΄μ˜ ν”„λ‘œν† νƒ€μž… κ°μ²΄λŠ” Array.prototype이닀.

typeof arr // -> object

const arr = [1, 2, 3];

arr.constructor === Array // -> true
Object.getPrototypeOf(arr) === Array.prototype // -> true

배열은 κ°μ²΄μ§€λ§Œ 일반 κ°μ²΄μ™€λŠ” 달리 κ°’μ˜ μˆœμ„œμ™€ length ν”„λ‘œνΌν‹°λ₯Ό κ°–λŠ”λ‹€. μ΄λŠ” λ°°μ—΄μ˜ μš”μ†Œμ— 순차적, μ—­μˆœ, νŠΉμ • μœ„μΉ˜μ— μ ‘κ·Όν• μˆ˜ μžˆκ²Œν•œλ‹€.

const arr = [1, 2, 3];

// 반볡문으둜 자료 ꡬ쑰λ₯Ό μˆœμ„œλŒ€λ‘œ μˆœνšŒν•˜κΈ° μœ„ν•΄μ„œλŠ” 자료 ꡬ쑰의 μš”μ†Œμ— μˆœμ„œλŒ€λ‘œ
// μ ‘κ·Όν•  수 μžˆμ–΄μ•Ό ν•˜λ©° 자료 ꡬ쑰의 길이λ₯Ό μ•Œ 수 μžˆμ–΄μ•Ό ν•œλ‹€.
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]); // 1 2 3
}


πŸ“ 27.2 μžλ°”μŠ€ν¬λ¦½νŠΈ 배열은 배열이 μ•„λ‹ˆλ‹€.

일반적인 μžλ£Œκ΅¬μ‘°μ—μ„œ λ§ν•˜λŠ” λ°°μ—΄μ˜ μš”μ†ŒλŠ” ν•˜λ‚˜μ˜ 데이터 νƒ€μž…μœΌλ‘œ ν†΅μΌλ˜μ–΄μžˆμœΌλ©° μ„œλ‘œ μ—°μ†μ μœΌλ‘œ μΈμ ‘ν•΄μžˆλ‹€. 이λ₯Ό 밀집 배열이라 ν•œλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œμ˜ 배열은 λ°°μ—΄μ˜ μš”μ†Œλ₯Ό μœ„ν•œ 각각의 λ©”λͺ¨λ¦¬ 곡간은 λ™μΌν•œ 크기λ₯Ό 갖지 μ•Šμ•„λ„ 되며, μ—°μ†μ μœΌλ‘œ 이어져 μžˆμ§€ μ•Šμ„ μˆ˜λ„ μžˆλ‹€. λ°°μ—΄μ˜ μš”μ†Œκ°€ μ—°μ†μ μœΌλ‘œ 이어져 μžˆμ§€ μ•ŠλŠ” 배열을 ν¬μ†Œ 배열이라 ν•œλ‹€. 즉, μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 배열은 일반적인 λ°°μ—΄μ˜ λ™μž‘μ„ 흉내낸 νŠΉμˆ˜ν•œ 객체이닀.

일반적인 λ°°μ—΄κ³Ό μžλ°”μŠ€ν¬λ¦½νŠΈ λ°°μ—΄μ˜ μž₯단점을 정리해보면 λ‹€μŒκ³Ό κ°™λ‹€.

  • 일반적인 배열은 인덱슀둜 μš”μ†Œμ— λΉ λ₯΄κ²Œ μ ‘κ·Όν•  수 μžˆλ‹€. ν•˜μ§€λ§Œ νŠΉμ • μš”μ†Œλ₯Ό κ²€μƒ‰ν•˜κ±°λ‚˜ μš”μ†Œλ₯Ό μ‚½μž… λ˜λŠ” μ‚­μ œν•˜λŠ” κ²½μš°μ—λŠ” νš¨μœ¨μ μ΄μ§€ μ•Šλ‹€.
  • μžλ°”μŠ€ν¬λ¦½νŠΈ 배열은 ν•΄μ‹œ ν…Œμ΄λΈ”λ‘œ κ΅¬μ„±λœ κ°μ²΄μ΄λ―€λ‘œ 인덱슀둜 μš”μ†Œμ— μ ‘κ·Όν•˜λŠ” 경우 일반적인 배열보닀 μ„±λŠ₯적인 λ©΄μ—μ„œ λŠλ¦΄μˆ˜λ°–μ— μ—†λŠ” ꡬ쑰적인 단점이 μžˆλ‹€. ν•˜μ§€λ§Œ νŠΉμ • μš”μ†Œλ₯Ό μ‚½μž… λ˜λŠ” μ‚­μ œν•˜λŠ” κ²½μš°μ—λŠ” 일반적인 배열보닀 λΉ λ₯Έ μ„±λŠ₯을 κΈ°λŒ€ν•  수 μžˆλ‹€.

πŸ“ 27.3 length ν”„λ‘œνΌν‹°μ™€ ν¬μ†Œ λ°°μ—΄

length ν”„λ‘œν”ΌνŠΈ 값은 μš”μ†Œμ˜ 개수, 즉 λ°°μ—΄μ˜ 길이λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 0μ΄μƒμ˜ μ •μˆ˜λ₯Ό κ°’μœΌλ‘œ κ°–λŠ”λ‹€. 일반적인 λ°°μ—΄μ˜ lengthλŠ” λ°°μ—΄ μš”μ†Œμ˜ 개수, 즉 λ°°μ—΄μ˜ 길이와 μ–Έμ œλ‚˜ μΌμΉ˜ν•˜μ§€λ§Œ ν¬μ†Œ λ°°μ—΄μ˜ lengthλŠ” ν¬μ†Œ λ°°μ—΄μ˜ μ‹€μ œ μš”μ†Œ κ°œμˆ˜λ³΄λ‹€ μ–Έμ œλ‚˜ 크닀.

μ˜λ„μ μœΌλ‘œ ν¬μ†Œ 배열을 λ§Œλ“€μ–΄μ•Ό ν•˜λŠ” 상황을 λ°œμƒν•˜μ§€ μ•ŠμœΌλ―€λ‘œ ν¬μ†Œλ°°μ—΄ μ‚¬μš©μ€ μ§€μ–‘ν•˜λŠ”κ²ƒμ΄ μ’‹λ‹€.

πŸ“ 27.4 λ°°μ—΄ 생성

βœ” 27.4.1 λ°°μ—΄ λ¦¬ν„°λŸ΄

λ°°μ—΄ λ¦¬ν„°λŸ΄μ€ 0개 μ΄μƒμ˜ μš”μ†Œλ₯Ό μ‰Όν‘œλ‘œ κ΅¬λΆ„ν•˜μ—¬ λŒ€κ΄„ν˜Έ([])둜 λ¬ΆλŠ”λ‹€.

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

βœ” 27.4.2 Array μƒμ„±μž ν•¨μˆ˜

Array μƒμ„±μž ν•¨μˆ˜λŠ” μ „λ‹¬λœ 인수의 κ°œμˆ˜μ— 따라 λ‹€μŒκ³Ό 같이 λ™μž‘ν•œλ‹€.

// μ „λ‹¬λœ μΈμˆ˜κ°€ 1개이고 숫자인 경우 length ν”„λ‘œνΌν‹° 값이 인수인 배열을 μƒμ„±ν•œλ‹€.
const arr = new Array(10);
console.log(arr); // [empty Γ— 10]
console.log(arr.length); // 10

// μ „λ‹¬λœ μΈμˆ˜κ°€ μ—†λŠ” 경우 빈 배열을 μƒμ„±ν•œλ‹€. 즉, λ°°μ—΄ λ¦¬ν„°λŸ΄ []κ³Ό κ°™λ‹€.
new Array(); // -> []

// μ „λ‹¬λœ μΈμˆ˜κ°€ 2개 이상이면 인수λ₯Ό μš”μ†Œλ‘œ κ°–λŠ” 배열을 μƒμ„±ν•œλ‹€.
new Array(1, 2, 3); // -> [1, 2, 3]

// μ „λ‹¬λœ μΈμˆ˜κ°€ 1κ°œμ§€λ§Œ μˆ«μžκ°€ μ•„λ‹ˆλ©΄ 인수λ₯Ό μš”μ†Œλ‘œ κ°–λŠ” 배열을 μƒμ„±ν•œλ‹€.
new Array({}); // -> [{}]

βœ” 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']

πŸ“ 27.5 λ°°μ—΄ μš”μ†Œμ˜ μ°Έμ‘°

λ°°μ—΄μ˜ μš”μ†Œλ₯Ό μ°Έμ‘°ν•  λ•Œμ—λŠ” λŒ€κ΄„ν˜Έ([]) ν‘œκΈ°λ²•μ„ μ‚¬μš©ν•œλ‹€.

const arr = [1, 2];

// μΈλ±μŠ€κ°€ 0인 μš”μ†Œλ₯Ό μ°Έμ‘°
console.log(arr[0]); // 1
// μΈλ±μŠ€κ°€ 1인 μš”μ†Œλ₯Ό μ°Έμ‘°
console.log(arr[1]); // 2

배열은 사싀 인덱슀λ₯Ό λ‚˜νƒ€λ‚΄λŠ” λ¬Έμžμ—΄μ„ ν”„λ‘œνΌν‹° ν‚€λ‘œ κ°–λŠ” 객체닀. λ”°λΌμ„œ μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” ν”„λ‘œνΌν‹° ν‚€λ‘œ 객체의 ν”„λ‘œνΌν‹°μ— μ ‘κ·Όν–ˆμ„λ•Œ undefinedλ₯Ό λ°˜ν™˜ν•˜λŠ” 것 처럼 배열도 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” μš”μ†Œλ₯Όμ°Έμ‘°ν•˜λ©΄ undefinedλ₯Ό λ°˜ν™˜ν•œλ‹€.

πŸ“ 27.6 λ°°μ—΄ μš”μ†Œμ˜ 좔가와 κ°±μ‹ 

배열은 κ°μ²΄μ΄λ―€λ‘œ λ™μ μœΌλ‘œ ν”„λ‘œνΌν‹°(μš”μ†Œ)λ₯Ό μΆ”κ°€ν•  수 μžˆλ‹€. μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” 인덱슀λ₯Ό μ‚¬μš©ν•΄ 값을 ν• λ‹Ήν•˜λ©΄ μƒˆλ‘œμš΄ μš”μ†Œκ°€ μΆ”κ°€λœλ‹€.

const arr = [0];

// λ°°μ—΄ μš”μ†Œμ˜ μΆ”κ°€
arr[1] = 1;

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

이미 μ‘΄μž¬ν•˜λŠ” μš”μ†Œμ— 값을 μž¬ν• λ‹Ήν•˜λ©΄ μš”μ†Œκ°’μ΄ κ°±μ‹ λœλ‹€. λ§Œμ•½ μ •μˆ˜ μ΄μ™Έμ˜ 값을 인덱슀처럼 μ‚¬μš©ν•˜λ©΄ μš”μ†Œκ°€ μƒμ„±λ˜λŠ”κ²ƒμ΄ μ•„λ‹ˆλΌ ν”„λ‘œνΌν‹°κ°€ μƒμ„±λ˜κ³  μ΄λŠ” length ν”„λ‘œνΌν‹° 값에 영ν–₯을 주지 μ•ŠλŠ”λ‹€.

// μš”μ†Œκ°’μ˜ κ°±μ‹ 
arr[1] = 10;
console.log(arr); // [0, 10, empty Γ— 98, 100]

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

πŸ“ 27.7 λ°°μ—΄ μš”μ†Œμ˜ μ‚­μ œ

배열은 사싀 객체이기 λ•Œλ¬Έμ— λ°°μ—΄μ˜ νŠΉμ • μš”μ†Œλ₯Ό μ‚­μ œν•˜κΈ° μœ„ν•΄ delete μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€. μ΄λ•Œ delete μ—°μ‚°μžλŠ” 객체의 ν”„λ‘œνΌν‹°λ₯Ό μ‚­μ œν•œλ‹€. λ”°λΌμ„œ 배열은 ν¬μ†Œ 배열이 되며 length ν”„λ‘œνΌν‹°μ˜ 값은 λ³€ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ delete μ—°μ‚°μžλŠ” μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”κ²ƒμ΄ μ’‹λ‹€.

const arr = [1, 2, 3];

// λ°°μ—΄ μš”μ†Œμ˜ μ‚­μ œ
delete arr[1];
console.log(arr); // [1, empty, 3]

// length ν”„λ‘œνΌν‹°μ— 영ν–₯을 주지 μ•ŠλŠ”λ‹€. 즉, ν¬μ†Œ 배열이 λœλ‹€.
console.log(arr.length); // 3

πŸ“ 27.8 λ°°μ—΄ λ©”μ„œλ“œ

βœ” 27.8.1 Array.isArray

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 λ©”μ„œλ“œλŠ” 원본 λ°°μ—΄μ—μ„œ 인수둜 μ „λ‹¬λœ μš”μ†Œλ₯Ό κ²€μƒ‰ν•˜μ—¬ 인덱슀λ₯Ό λ°˜ν™˜ν•œλ‹€.

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

// λ°°μ—΄ arrμ—μ„œ μš”μ†Œ 2λ₯Ό κ²€μƒ‰ν•˜μ—¬ 첫 번째둜 κ²€μƒ‰λœ μš”μ†Œμ˜ 인덱슀λ₯Ό λ°˜ν™˜ν•œλ‹€.
arr.indexOf(2);    // -> 1
// λ°°μ—΄ arr에 μš”μ†Œ 4κ°€ μ—†μœΌλ―€λ‘œ -1을 λ°˜ν™˜ν•œλ‹€.
arr.indexOf(4);    // -> -1
// 두 번째 μΈμˆ˜λŠ” 검색을 μ‹œμž‘ν•  μΈλ±μŠ€λ‹€. 두 번째 인수λ₯Ό μƒλž΅ν•˜λ©΄ μ²˜μŒλΆ€ν„° κ²€μƒ‰ν•œλ‹€.
arr.indexOf(2, 2); // -> 2
const foods = ['apple', 'banana', 'orange'];

// foods 배열에 'orange' μš”μ†Œκ°€ μ‘΄μž¬ν•˜λŠ”μ§€ ν™•μΈν•œλ‹€.
if (foods.indexOf('orange') === -1) {
  // foods 배열에 'orange' μš”μ†Œκ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ©΄ 'orange' μš”μ†Œλ₯Ό μΆ”κ°€ν•œλ‹€.
  foods.push('orange');
}

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

βœ” 27.8.3 Array.prototype.push

push λ©”μ„œλ“œλŠ” 인수둜 전달받은 λͺ¨λ“  값을 원본 λ°°μ—΄μ˜ λ§ˆμ§€λ§‰ μš”μ†Œλ‘œ μΆ”κ°€ν•˜κ³  λ³€κ²½λœ length ν”„λ‘œνΌν‹° 값을 λ°˜ν™˜ν•œλ‹€. push λ©”μ„œλ“œλŠ” 원본 배열을 직접 λ³€κ²½ν•œλ‹€.

const arr = [1, 2];

// 인수둜 전달받은 λͺ¨λ“  값을 원본 λ°°μ—΄ arr의 λ§ˆμ§€λ§‰ μš”μ†Œλ‘œ μΆ”κ°€ν•˜κ³  λ³€κ²½λœ length 값을 λ°˜ν™˜ν•œλ‹€.
let result = arr.push(3, 4);
console.log(result); // 4

// push λ©”μ„œλ“œλŠ” 원본 배열을 직접 λ³€κ²½ν•œλ‹€.
console.log(arr); // [1, 2, 3, 4]

push λ©”μ„œλ“œλŠ” μ„±λŠ₯ λ©΄μ—μ„œ 쒋지 μ•Šλ‹€. λ§ˆμ§€λ§‰ μš”μ†Œλ‘œ μΆ”κ°€ν•  μš”μ†Œκ°€ ν•˜λ‚˜λΏμ΄λΌλ©΄ length ν”„λ‘œνΌν‹°λ₯Ό μ‚¬μš©ν•˜μ—¬ λ°°μ—΄μ˜ λ§ˆμ§€λ§‰ μš”μ†Œμ— 직접 μΆ”κ°€ν•˜λŠ”κ²ƒμ΄ 더 λΉ λ₯΄λ‹€.

const arr = [1, 2];

// arr.push(3)κ³Ό λ™μΌν•œ 처리λ₯Ό ν•œλ‹€. 이 방법이 push λ©”μ„œλ“œλ³΄λ‹€ λΉ λ₯΄λ‹€.
arr[arr.length] = 3;
console.log(arr); // [1, 2, 3]

βœ” 27.8.4 Array.prototype.pop

pop λ©”μ„œλ“œλŠ” 원본 λ°°μ—΄μ—μ„œ λ§ˆμ§€λ§‰ μš”μ†Œλ₯Ό μ œκ±°ν•˜κ³  μ œκ±°ν•œ μš”μ†Œλ₯Ό λ°˜ν™˜ν•œλ‹€. 원본 배열이 빈 배열이면 undefinedλ₯Ό λ°˜ν™˜ν•œλ‹€. push λ©”μ„œλ“œλŠ” 원본 배열을 직접 λ³€κ²½ν•œλ‹€.

const arr = [1, 2];

// 원본 λ°°μ—΄μ—μ„œ λ§ˆμ§€λ§‰ μš”μ†Œλ₯Ό μ œκ±°ν•˜κ³  μ œκ±°ν•œ μš”μ†Œλ₯Ό λ°˜ν™˜ν•œλ‹€.
let result = arr.pop();
console.log(result); // 2

// pop λ©”μ„œλ“œλŠ” 원본 배열을 직접 λ³€κ²½ν•œλ‹€.
console.log(arr); // [1]

pop λ©”μ„œλ“œμ™€ pusth λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ μŠ€νƒμ„ μ‰½κ²Œ κ΅¬ν˜„ν•  수 μžˆλ‹€.

🧐 μŠ€νƒ(stack)

μŠ€νƒμ€ 데이터λ₯Ό λ§ˆμ§€λ§‰μ— λ°€μ–΄ λ„£κ³ , λ§ˆμ§€λ§‰μ— λ°€μ–΄ 넣은 데이터λ₯Ό λ¨Όμ € κΊΌλ‚΄λŠ” ν›„μž… μ„ μΆœ(LIFO - Last In First Out) λ°©μ‹μ˜ μžλ£Œκ΅¬μ‘°μ΄λ‹€. μ•„λž˜ μ˜ˆμ œλŠ” μŠ€νƒμ„ μƒμ„±μž ν•¨μˆ˜ / 클래슀둜 λ‚˜νƒ€λ‚Έ 것이닀.

const Stack = (function () {
  function Stack(array = []) {
    if (!Array.isArray(array)) {
      // "47. μ—λŸ¬ 처리" μ°Έκ³ 
      throw new TypeError(`${array} is not an array.`);
    }
    this.array = array;
  }
Stack.prototype = {
    // "19.10.1. μƒμ„±μž ν•¨μˆ˜μ— μ˜ν•œ ν”„λ‘œν† νƒ€μž…μ˜ ꡐ체" μ°Έκ³ 
    constructor: Stack,
    // μŠ€νƒμ˜ κ°€μž₯ λ§ˆμ§€λ§‰μ— 데이터λ₯Ό λ°€μ–΄ λ„£λŠ”λ‹€.
    push(value) {
      return this.array.push(value);
    },
    // μŠ€νƒμ˜ κ°€μž₯ λ§ˆμ§€λ§‰ 데이터, 즉 κ°€μž₯ λ‚˜μ€‘μ— λ°€μ–΄ 넣은 μ΅œμ‹  데이터λ₯Ό κΊΌλ‚Έλ‹€.
    pop() {
      return this.array.pop();
    },
    // μŠ€νƒμ˜ 볡사본 배열을 λ°˜ν™˜ν•œλ‹€.
    entries() {
      return [...this.array];
    }
  };
return Stack;
}());
const stack = new Stack([1, 2]);
console.log(stack.entries()); // [1, 2]
stack.push(3);
console.log(stack.entries()); // [1, 2, 3]
stack.pop();
console.log(stack.entries()); // [1, 2]
``````jsx
class Stack {
  #array; // private class member
	constructor(array = []) {
    if (!Array.isArray(array)) {
      throw new TypeError(`${array} is not an array.`);
    }
    this.#array = array;
  }
	// μŠ€νƒμ˜ κ°€μž₯ λ§ˆμ§€λ§‰μ— 데이터λ₯Ό λ°€μ–΄ λ„£λŠ”λ‹€.
  push(value) {
    return this.#array.push(value);
  }
  // μŠ€νƒμ˜ κ°€μž₯ λ§ˆμ§€λ§‰ 데이터, 즉 κ°€μž₯ λ‚˜μ€‘μ— λ°€μ–΄ 넣은 μ΅œμ‹  데이터λ₯Ό κΊΌλ‚Έλ‹€.
  pop() {
    return this.#array.pop();
  }
  // μŠ€νƒμ˜ 볡사본 배열을 λ°˜ν™˜ν•œλ‹€.
  entries() {
    return [...this.#array];
  }
}
const stack = new Stack([1, 2]);
console.log(stack.entries()); // [1, 2]
stack.push(3);
console.log(stack.entries()); // [1, 2, 3]
stack.pop();
console.log(stack.entries()); // [1, 2]

βœ” 27.8.5 Array.prototype.unshift

unshift λ©”μ„œλ“œλŠ” 인수둜 전달받은 λͺ¨λ“  값을 원본 λ°°μ—΄μ˜ 선두에 μš”μ†Œλ‘œ μΆ”κ°€ν•˜κ³  λ³€κ²½λœ length ν”„λ‘œνΌν‹° 값을 λ°˜ν™˜ν•œλ‹€. unshift λ©”μ„œλ“œλŠ” 원본 배열을 직접 λ³€κ²½ν•œλ‹€.

const arr = [1, 2];

// 인수둜 전달받은 λͺ¨λ“  값을 원본 λ°°μ—΄μ˜ 선두에 μš”μ†Œλ‘œ μΆ”κ°€ν•˜κ³  λ³€κ²½λœ length 값을 λ°˜ν™˜ν•œλ‹€.
let result = arr.unshift(3, 4);
console.log(result); // 4

// unshift λ©”μ„œλ“œλŠ” 원본 배열을 직접 λ³€κ²½ν•œλ‹€.
console.log(arr); // [3, 4, 1, 2]

βœ” 27.8.6 Array.prototype.shift

shift λ©”μ„œλ“œλŠ” 원본 λ°°μ—΄μ—μ„œ 첫 번째 μš”μ†Œλ₯Ό μ œκ±°ν•˜κ³  μ œκ±°ν•œ μš”μ†Œλ₯Ό λ°˜ν™˜ν•œλ‹€. 원본 배열이 빈 배열이면 undefinedλ₯Ό λ°˜ν™˜ν•œλ‹€. shift λ©”μ„œλ“œλŠ” 원본 배열을 직접 λ³€κ²½ν•œλ‹€.

const arr = [1, 2];

// 원본 λ°°μ—΄μ—μ„œ 첫 번째 μš”μ†Œλ₯Ό μ œκ±°ν•˜κ³  μ œκ±°ν•œ μš”μ†Œλ₯Ό λ°˜ν™˜ν•œλ‹€.
let result = arr.shift();
console.log(result); // 1

// shift λ©”μ„œλ“œλŠ” 원본 배열을 직접 λ³€κ²½ν•œλ‹€.
console.log(arr); // [2]

shift λ©”μ„œλ“œμ™€ push λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ 큐λ₯Ό μ‰½κ²Œ κ΅¬ν˜„ν•  수 μžˆλ‹€.

🧐 큐(queue)

νλŠ” 데이터λ₯Ό λ§ˆμ§€λ§‰μ— λ°€μ–΄ λ„£κ³ , κ°€μž₯ λ¨Όμ € λ°€μ–΄ 넣은 데이터λ₯Ό λ¨Όμ € κΊΌλ‚΄λŠ” μ„ μž… μ„ μΆœ(FIFO - First in First Out) λ°©μ‹μ˜ μžλ£Œκ΅¬μ‘°μ΄λ‹€. μ•„λž˜ μ˜ˆμ œλŠ” 큐λ₯Ό μƒμ„±μž ν•¨μˆ˜ / 클래슀둜 λ‚˜νƒ€λ‚Έ 것이닀.

const Queue = (function () {
  function Queue(array = []) {
    if (!Array.isArray(array)) {
      // "47. μ—λŸ¬ 처리" μ°Έκ³ 
      throw new TypeError(`${array} is not an array.`);
    }
    this.array = array;
  }
	Queue.prototype = {
    // "19.10.1. μƒμ„±μž ν•¨μˆ˜μ— μ˜ν•œ ν”„λ‘œν† νƒ€μž…μ˜ ꡐ체" μ°Έκ³ 
    constructor: Queue,
    // 큐의 κ°€μž₯ λ§ˆμ§€λ§‰μ— 데이터λ₯Ό λ°€μ–΄ λ„£λŠ”λ‹€.
    enqueue(value) {
      return this.array.push(value);
    },
    // 큐의 κ°€μž₯ 처음 데이터, 즉 κ°€μž₯ λ¨Όμ € λ°€μ–΄ 넣은 데이터λ₯Ό κΊΌλ‚Έλ‹€.
    dequeue() {
      return this.array.shift();
    },
    // 큐의 볡사본 배열을 λ°˜ν™˜ν•œλ‹€.
    entries() {
      return [...this.array];
    }
  };
return Queue;
}());
const queue = new Queue([1, 2]);
console.log(queue.entries()); // [1, 2]
queue.enqueue(3);
console.log(queue.entries()); // [1, 2, 3]
queue.dequeue();
console.log(queue.entries()); // [2, 3]
class Queue {
  #array; // private class member
  constructor(array = []) {
    if (!Array.isArray(array)) {
      throw new TypeError(`${array} is not an array.`);
    }
    this.#array = array;
  }
  // 큐의 κ°€μž₯ λ§ˆμ§€λ§‰μ— 데이터λ₯Ό λ°€μ–΄ λ„£λŠ”λ‹€.
  enqueue(value) {
    return this.#array.push(value);
  }
  // 큐의 κ°€μž₯ 처음 데이터, 즉 κ°€μž₯ λ¨Όμ € λ°€μ–΄ 넣은 데이터λ₯Ό κΊΌλ‚Έλ‹€.
  dequeue() {
    return this.#array.shift();
  }
  // 큐의 볡사본 배열을 λ°˜ν™˜ν•œλ‹€.
  entries() {
    return [...this.#array];
  }
}
const queue = new Queue([1, 2]);
console.log(queue.entries()); // [1, 2]
queue.enqueue(3);
console.log(queue.entries()); // [1, 2, 3]
queue.dequeue();
console.log(queue.entries()); // [2, 3]

βœ” 27.8.7 Array.prototype.concat

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]

βœ” 27.8.8 Array.prototype.splice

pusth, pop, unshift, shift λ©”μ„œλ“œλŠ” λͺ¨λ‘ 원본 배열을 직접 λ³€κ²½ν•˜λŠ” λ©”μ„œλ“œμ΄λ©° 원본 λ°°μ—΄μ˜ μ²˜μŒμ΄λ‚˜ λ§ˆμ§€λ§‰ μš”μ†Œλ₯Ό μΆ”κ°€ν•˜κ±°λ‚˜ μ œκ±°ν•œλ‹€.

원본 λ°°μ—΄μ˜ 쀑간에 μš”μ†Œλ₯Ό μΆ”κ°€ν•˜κ±°λ‚˜ μ œκ±°ν•˜λŠ” 경우 splice λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•œλ‹€.

splice λ©”μ„œλ“œλŠ” 3개의 λ§€κ°œλ³€μˆ˜κ°€ 있으며 원본 배열을 직접 λ³€κ²½ν•˜κ³  λ³€κ²½λœ μš”μ†Œλ₯Ό λ°˜ν™˜ν•œλ‹€.

  • start : 원본 λ°°μ—΄μ˜ μš”μ†Œλ₯Ό μ œκ±°ν•˜κΈ° μ‹œμž‘ν•  μΈλ±μŠ€μ΄λ‹€. start만 μ§€μ •ν•˜λ©΄ 원본 λ°°μ—΄μ˜ λͺ¨λ“  μš”μ†Œλ₯Ό μ œκ±°ν•œλ‹€. startκ°€ 음수일 경우 λ°°μ—΄μ˜ λμ—μ„œμ˜ 인덱슀λ₯Ό λ‚˜νƒ€λ‚Έλ‹€.
  • deleteCount(μ˜΅μ…˜) : 원본 λ°°μ—΄μ˜ μš”μ†Œλ₯Ό μ œκ±°ν•˜κΈ° μ‹œμž‘ν•  인덱슀인 startλΆ€ν„° μ œκ±°ν•  μš”μ†Œμ˜ κ°œμˆ˜μ΄λ‹€. deleteCountκ°€ 0인 경우 μ•„λ¬΄λŸ° μš”μ†Œλ„ μ œκ±°λ˜μ§€ μ•ŠλŠ”λ‹€.
  • items(μ˜΅μ…˜) : μ œκ±°ν•œ μœ„μΉ˜μ— μ‚½μž…ν•  μš”μ†Œλ“€μ˜ λͺ©λ‘μ΄λ‹€. μƒλž΅ν•  경우 원본 λ°°μ—΄μ—μ„œ μš”μ†Œλ₯Ό μ œκ±°ν•˜κΈ°λ§Œ ν•œλ‹€.
const arr = [1, 2, 3, 4];

// 원본 λ°°μ—΄μ˜ 인덱슀 1λΆ€ν„° 2개의 μš”μ†Œλ₯Ό μ œκ±°ν•˜κ³  κ·Έ μžλ¦¬μ— μƒˆλ‘œμš΄ μš”μ†Œ 20, 30을 μ‚½μž…ν•œλ‹€.
const result_1 = arr.splice(1, 2, 20, 30);

// 원본 λ°°μ—΄μ˜ 인덱슀 1λΆ€ν„° 0개의 μš”μ†Œλ₯Ό μ œκ±°ν•˜κ³  κ·Έ μžλ¦¬μ— μƒˆλ‘œμš΄ μš”μ†Œ 100을 μ‚½μž…ν•œλ‹€.
const result_2 = arr.splice(1, 0, 100);

// 원본 λ°°μ—΄μ˜ 인덱슀 1λΆ€ν„° 2개의 μš”μ†Œλ₯Ό μ œκ±°ν•œλ‹€.
const result_3 = arr.splice(1, 2);

// 원본 λ°°μ—΄μ˜ 인덱슀 1λΆ€ν„° λͺ¨λ“  μš”μ†Œλ₯Ό μ œκ±°ν•œλ‹€.
const result_4 = arr.splice(1);

λ°°μ—΄μ—μ„œ νŠΉμ • μš”μ†Œλ₯Ό μ œκ±°ν•˜λ €λ©΄ indexOf λ©”μ„œλ“œλ₯Ό 톡해 νŠΉμ • μš”μ†Œμ˜ 인덱슀λ₯Ό μ·¨λ“ν•œ λ‹€μŒ splice λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•œλ‹€.

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

// λ°°μ—΄ arrayμ—μ„œ item μš”μ†Œλ₯Ό μ œκ±°ν•œλ‹€. item μš”μ†Œκ°€ μ—¬λŸ¬ 개 μ‘΄μž¬ν•˜λ©΄ 첫 번째 μš”μ†Œλ§Œ μ œκ±°ν•œλ‹€.
function remove(array, item) {
  // μ œκ±°ν•  item μš”μ†Œμ˜ 인덱슀λ₯Ό μ·¨λ“ν•œλ‹€.
  const index = array.indexOf(item);

  // μ œκ±°ν•  item μš”μ†Œκ°€ μžˆλ‹€λ©΄ μ œκ±°ν•œλ‹€.
  if (index !== -1) array.splice(index, 1);

  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 λ©”μ„œλ“œλŠ” 인수둜 μ „λ‹¬λœ λ²”μœ„μ˜ μš”μ†Œλ“€μ„ λ³΅μ‚¬ν•˜μ—¬ λ°°μ—΄λ‘œ λ°˜ν™˜ν•œλ‹€. 원본 배열은 λ³€κ²½λ˜μ§€ μ•ŠλŠ”λ‹€. slice λ©”μ„œλ“œλŠ” λ‘κ°œμ˜ λ°°κ°œλ³€μˆ˜λ₯Ό κ°–λŠ”λ‹€.

  • start : 볡사λ₯Ό μ‹œμž‘ν•  μΈλ±μŠ€λ‹€. 음수인 경우 λ°°μ—΄ λμ—μ„œμ˜ 인덱슀λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. 음수일 경우 λ°°μ—΄ λμ—μ„œμ˜ 인덱슀λ₯Ό λ‚˜νƒ€λ‚Έλ‹€.
  • end(μ˜΅μ…˜) : 볡사λ₯Ό μ’…λ£Œν•  μΈλ±μŠ€λ‹€. 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]

// λ°°μ—΄μ˜ λμ—μ„œλΆ€ν„° μš”μ†Œλ₯Ό ν•œ 개 λ³΅μ‚¬ν•˜μ—¬ λ°˜ν™˜ν•œλ‹€.
arr.slice(-1); // -> [3]

// λ°°μ—΄μ˜ λμ—μ„œλΆ€ν„° μš”μ†Œλ₯Ό 두 개 λ³΅μ‚¬ν•˜μ—¬ λ°˜ν™˜ν•œλ‹€.
arr.slice(-2); // -> [2, 3]

// 원본은 λ³€κ²½λ˜μ§€ μ•ŠλŠ”λ‹€.
console.log(arr); // [1, 2, 3]

slice λ©”μ„œλ“œμ˜ 인수λ₯Ό λͺ¨λ‘ μƒλž΅ν•˜λ©΄ 원본 λ°°μ—΄μ˜ 볡사본을 생성해 λ°˜ν™˜ν•œλ‹€. μ΄λ•Œ μƒμ„±λœ 볡사본은 얕은 볡사λ₯Ό 톡해 μƒμ„±λœλ‹€.

const arr = [1, 2, 3];

// 인수λ₯Ό λͺ¨λ‘ μƒλž΅ν•˜λ©΄ 원본 λ°°μ—΄μ˜ 볡사본을 μƒμ„±ν•˜μ—¬ λ°˜ν™˜ν•œλ‹€.
const copy = arr.slice();
console.log(copy); // [1, 2, 3]
console.log(copy === arr); // false

🧐 얕은볡사와 κΉŠμ€λ³΅μ‚¬

객체λ₯Ό ν”„λ‘œνΌν‹° κ°’μœΌλ‘œ κ°–λŠ” 객체의 경우 얕은 λ³΅μ‚¬λŠ” ν•œ λ‹¨κ³„κΉŒμ§€λ§Œ λ³΅μ‚¬ν•˜λŠ” 것을 λ§ν•˜κ³  κΉŠμ€ λ³΅μ‚¬λŠ” 객체에 μ€‘μ²©λ˜μ–΄ μžˆλŠ” κ°μ²΄κΉŒμ§€ λͺ¨λ‘ λ³΅μ‚¬ν•˜λŠ” 것을 λ§ν•œλ‹€. slice λ©”μ„œλ“œ, μŠ€ν”„λ ˆλ“œ 문법, Object.assign λ©”μ„œλ“œλŠ” λͺ¨λ‘ 얕은 볡사λ₯Ό μˆ˜ν–‰ν•œλ‹€.

βœ” 27.8.10 Array.prototype.join

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'

βœ” 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

fill λ©”μ„œλ“œλŠ” 인수둜 전달받은 값을 λ°°μ—΄μ˜ μ²˜μŒλΆ€ν„° λκΉŒμ§€ μš”μ†Œλ‘œ μ±„μš΄λ‹€. μ΄λ•Œ 원본 배열이 λ³€κ²½λœλ‹€.

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

// 인수둜 전달 받은 κ°’ 0을 λ°°μ—΄μ˜ μ²˜μŒλΆ€ν„° λκΉŒμ§€ μš”μ†Œλ‘œ μ±„μš΄λ‹€.
arr.fill(0);
console.log(arr); // [0, 0, 0, 0, 0]

// 인수둜 전달받은 κ°’ 0을 λ°°μ—΄μ˜ 인덱슀 1λΆ€ν„° λκΉŒμ§€ μš”μ†Œλ‘œ μ±„μš΄λ‹€.
arr.fill(5, 1);
console.log(arr); // [0, 5, 5, 5, 5]

// 인수둜 전달받은 κ°’ 0을 λ°°μ—΄μ˜ 인덱슀 1λΆ€ν„° 3 이전(인덱슀 3 미포함)κΉŒμ§€ μš”μ†Œλ‘œ μ±„μš΄λ‹€.
arr.fill(7, 1, 3);
console.log(arr); // [0, 7, 7, 5, 5]

fill λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ 배열을 μƒμ„±ν•˜λ©΄μ„œ νŠΉμ • κ°’μœΌλ‘œ μš”μ†Œλ₯Ό μ±„μšΈ 수 μžˆλ‹€.

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]

βœ” 27.8.13 Array.prototype.includes

includes λ©”μ„œλ“œλŠ” λ°°μ—΄ 내에 νŠΉμ • μš”μ†Œκ°€ ν¬ν•¨λ˜μ–΄ μžˆλŠ”μ§€ ν™•μΈν•˜μ—¬ true λ˜λŠ” falseλ₯Ό λ°˜ν™˜ν•œλ‹€. 첫 번째 인수둜 검색할 λŒ€μƒμ„ μ§€μ •ν•œλ‹€.

const arr = [1, 2, 3];

// 배열에 μš”μ†Œ 2κ°€ ν¬ν•¨λ˜μ–΄ μžˆλŠ”μ§€ ν™•μΈν•œλ‹€.
arr.includes(2); // -> true

// 배열에 μš”μ†Œ 100이 ν¬ν•¨λ˜μ–΄ μžˆλŠ”μ§€ ν™•μΈν•œλ‹€.
arr.includes(100); // -> false

두 번째 인수둜 검색을 μ‹œμž‘ν•  인덱슀λ₯Ό 전달할 수 μžˆλ‹€. 두 번째 인수λ₯Ό μƒλž΅ν•  경우 κΈ°λ³Έκ°’ 0이 μ„€μ •λœλ‹€. λ§Œμ•½ 두 번째 μΈμˆ˜μ— 음수λ₯Ό μ „λ‹¬ν•˜λ©΄ length ν”„λ‘œνΌν‹° κ°’κ³Ό 음수 인덱슀λ₯Ό ν•©μ‚°ν•˜μ—¬(length+index) 검색 μ‹œμž‘ 인덱슀λ₯Ό μ„€μ •ν•œλ‹€.

const arr = [1, 2, 3];

// 배열에 μš”μ†Œ 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, 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]

πŸ“ 27.9 λ°°μ—΄ κ³ μ°¨ ν•¨μˆ˜

κ³ μ°¨ ν•¨μˆ˜λŠ” ν•¨μˆ˜λ₯Ό 인수둜 μ „λ‹¬λ°›κ±°λ‚˜ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ§ν•œλ‹€. ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ€ μˆœμˆ˜ν•¨μˆ˜μ™€ 보쑰 ν•¨μˆ˜μ˜ 쑰합을 톡해 둜직 내에 μ‘΄μž¬ν•˜λŠ” 쑰건문과 λ°˜λ³΅λ¬Έμ„ μ œκ±°ν•˜μ—¬ λ³΅μž‘μ„±μ„ ν•΄κ²°ν•˜κ³  λ³€μˆ˜μ˜ μ‚¬μš©μ„ μ–΅μ œν•˜μ—¬ μƒνƒœ 변경을 ν”Όν•˜λ €λŠ” νŒ¨λŸ¬λ‹€μž„μ΄λ‹€.

βœ” 27.9.1 Array.prototype.sort

sort λ©”μ„œλ“œλŠ” λ°°μ—΄μ˜ μš”μ†Œλ₯Ό μ˜€λ¦„μ°¨μˆœμœΌλ‘œ μ •λ ¬ν•œλ‹€. 원본 배열을 직접 λ³€κ²½ν•˜λ©° μ •λ ¬λœ 배열을 λ°˜ν™˜ν•œλ‹€.

const fruits = ['Banana', 'Orange', 'Apple'];

// μ˜€λ¦„μ°¨μˆœ(ascending) μ •λ ¬
fruits.sort();

// sort λ©”μ„œλ“œλŠ” 원본 배열을 직접 λ³€κ²½ν•œλ‹€.
console.log(fruits); // ['Apple', 'Banana', 'Orange']

sort λ©”μ„œλ“œμ˜ κΈ°λ³Έ μ •λ ¬ μˆœμ„œλŠ” μœ λ‹ˆμ½”λ“œ μ½”λ“œν¬μΈνŠΈμ˜ μˆœμ„œλ₯Ό λ”°λ₯Έλ‹€. λ”°λΌμ„œ 숫자 μš”μ†Œλ₯Ό μ •λ ¬ν•  λ•ŒλŠ” sort λ©”μ„œλ“œμ— μ •λ ¬ μˆœμ„œλ₯Ό μ •μ˜ν•˜λŠ” 비ꡐ ν•¨μˆ˜λ₯Ό 인수둜 전달해야 ν•œλ‹€. 비ꡐ ν•¨μˆ˜λŠ” μ–‘μˆ˜λ‚˜ 음수 λ˜λŠ” 0을 λ°˜ν™˜ν•΄μ•Ό ν•œλ‹€.

🧐 λΉ„κ΅ν•¨μˆ˜

compareFunction νŒŒλΌλ―Έν„°λŠ” λ‹€μŒκ³Ό 같이 sort λ©”μ„œλ“œμ˜ 인수둜 μ „λ‹¬λœλ‹€. compareFunctionλ₯Ό μ„ μ–Έν•  경우 sort() ν•¨μˆ˜λŠ” compareFunction μ—κ²Œ λ°°μ—΄μ˜ μš”μ†Œ 2가지λ₯Ό λ°˜λ³΅ν•΄μ„œ 보낸 λ’€, compareFunction이 λ°˜ν™˜ν•˜λŠ” 값을 κΈ°μ€€μœΌλ‘œ 정렬을 ν•œλ‹€.

  • λ°˜ν™˜κ°’ < 0 : aκ°€ b보닀 μ•žμ— μžˆμ–΄μ•Ό ν•œλ‹€.
  • λ°˜ν™˜κ°’ = 0 : a와 b의 μˆœμ„œλ₯Ό 바꾸지 μ•ŠλŠ”λ‹€.
  • λ°˜ν™˜κ°’ > 0 : bκ°€ a보닀 μ•žμ— μžˆμ–΄μ•Ό ν•œλ‹€.
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]
// 숫자 λ°°μ—΄μ—μ„œ μ΅œμ†Œ/μ΅œλŒ€κ°’ 취득
console.log(points[0], points[points.length]); // 1 100
// 숫자 λ°°μ—΄μ˜ λ‚΄λ¦Όμ°¨μˆœ μ •λ ¬. 비ꡐ ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μ΄ 0보닀 μž‘μœΌλ©΄ bλ₯Ό μš°μ„ ν•˜μ—¬ μ •λ ¬ν•œλ‹€.
points.sort((a, b) => b - a);
console.log(points); // [100, 40, 25, 10, 5, 2, 1]
// 숫자 λ°°μ—΄μ—μ„œ μ΅œλŒ€κ°’ 취득
console.log(points[0]); // 100

객체λ₯Ό μš”μ†Œλ‘œ κ°–λŠ” 배열을 μ •λ¦¬ν•˜λŠ” μ˜ˆμ œλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

const todos = [
  { id: 4, content: 'JavaScript' },
  { id: 1, content: 'HTML' },
  { id: 2, content: 'CSS' }
];
// 비ꡐ ν•¨μˆ˜. λ§€κ°œλ³€μˆ˜ keyλŠ” ν”„λ‘œνΌν‹° ν‚€λ‹€.
function compare(key) {
  // ν”„λ‘œνΌν‹° 값이 λ¬Έμžμ—΄μΈ 경우 - μ‚°μˆ  μ—°μ‚°μœΌλ‘œ λΉ„κ΅ν•˜λ©΄ NaN이 λ‚˜μ˜€λ―€λ‘œ 비ꡐ 연산을 μ‚¬μš©ν•œλ‹€.
  // 비ꡐ ν•¨μˆ˜λŠ” μ–‘μˆ˜/음수/0을 λ°˜ν™˜ν•˜λ©΄ λ˜λ―€λ‘œ - μ‚°μˆ  μ—°μ‚° λŒ€μ‹  비ꡐ 연산을 μ‚¬μš©ν•  수 μžˆλ‹€.
  return (a, b) => (a[key] > b[key] ? 1 : (a[key] < b[key] ? -1 : 0));
}
// idλ₯Ό κΈ°μ€€μœΌλ‘œ μ˜€λ¦„μ°¨μˆœ μ •λ ¬
todos.sort(compare('id'));
console.log(todos);
/*
[
  { id: 1, content: 'HTML' },
  { id: 2, content: 'CSS' },
  { id: 4, content: 'JavaScript' }
]
*/
// contentλ₯Ό κΈ°μ€€μœΌλ‘œ μ˜€λ¦„μ°¨μˆœ μ •λ ¬
todos.sort(compare('content'));
console.log(todos);
/*
[
  { id: 2, content: 'CSS' },
  { id: 1, content: 'HTML' },
  { id: 4, content: 'JavaScript' }
]
*/

μ •λ ¬ν•  λ°°μ—΄μ˜ μš”μ†Œμ˜ κ°œμˆ˜κ°€ 2개 미만일 경우 β€˜sort is not a function’ 였λ₯˜κ°€ λ‚œλ‹€.

βœ” 27.9.2 Array.prototype.forEach

forEach λ©”μ„œλ“œλŠ” μžμ‹ μ˜ λ‚΄λΆ€μ—μ„œ λ°˜λ³΅λ¬Έμ„ 톡해 μžμ‹ μ„ ν˜ΈμΆœν•œ 배열을 μˆœνšŒν•˜λ©΄μ„œ μˆ˜ν–‰ν•΄μ•Όν•  처리λ₯Ό 콜백 ν•¨μˆ˜λ‘œ 전달받아 반볡 ν˜ΈμΆœν•œλ‹€. forEach λ©”μ„œλ“œλŠ” μ–Έμ œλ‚˜ undefinedλ₯Ό λ°˜ν™˜ν•œλ‹€.

const numbers = [1, 2, 3];
let pows = [];

// forEach λ©”μ„œλ“œλŠ” numbers λ°°μ—΄μ˜ λͺ¨λ“  μš”μ†Œλ₯Ό μˆœνšŒν•˜λ©΄μ„œ 콜백 ν•¨μˆ˜λ₯Ό 반볡 ν˜ΈμΆœν•œλ‹€.
numbers.forEach(item => pows.push(item ** 2));
console.log(pows); // [1, 4, 9]

forEach λ©”μ„œλ“œμ˜ 콜백 ν•¨μˆ˜λŠ” forEach λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄μ˜ μš”μ†Œκ°’κ³Ό 인덱슀, foeEach λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄ 자체, 즉 thisλ₯Ό 순차적으둜 전달받을 수 μžˆλ‹€.

// forEach λ©”μ„œλ“œλŠ” 콜백 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄μ„œ 3개(μš”μ†Œκ°’, 인덱슀, this)의 인수λ₯Ό μ „λ‹¬ν•œλ‹€.
[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 λ©”μ„œλ“œλŠ” 원본 λ°°μ—΄(this)λ₯Ό λ³€κ²½ν•˜μ§€λŠ” μ•Šμ§€λ§Œ 콜백 ν•¨μˆ˜λ₯Ό 톡해 원본 배열을 λ³€κ²½ν•  수 μžˆλ‹€.

const numbers = [1, 2, 3];

// forEach λ©”μ„œλ“œλŠ” 원본 배열을 λ³€κ²½ν•˜μ§€ μ•Šμ§€λ§Œ 콜백 ν•¨μˆ˜λ₯Ό 톡해 원본 배열을 λ³€κ²½ν•  μˆ˜λŠ” μžˆλ‹€.
// 콜백 ν•¨μˆ˜μ˜ μ„Έ 번째 λ§€κ°œλ³€μˆ˜ arr은 원본 λ°°μ—΄ numbersλ₯Ό 가리킨닀.
// λ”°λΌμ„œ 콜백 ν•¨μˆ˜μ˜ μ„Έ 번째 λ§€κ°œλ³€μˆ˜ arr을 직접 λ³€κ²½ν•˜λ©΄ 원본 λ°°μ—΄ numbersκ°€ λ³€κ²½λœλ‹€.
numbers.forEach((item, index, arr) => { arr[index] = item ** 2; });
console.log(numbers); // [1, 4, 9]

forEach λ©”μ„œλ“œμ˜ λ‘λ²ˆμ§Έ 인수둜 forEach λ©”μ„œλ“œμ˜ μ½œλ°±ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ this둜 μ‚¬μš©ν•  객체λ₯Ό 전달할 수 μžˆλ‹€. λ‹€μŒ μ˜ˆμ œμ—μ„œ forEach λ©”μ„œλ“œμ˜ 콜백 ν•¨μˆ˜ λ‚΄λΆ€μ˜ this와 multyply λ©”μ„œλ“œ λ‚΄λΆ€μ˜ thisλ₯Ό μΌμΉ˜μ‹œν‚€λ €λ©΄ forEach λ©”μ„œλ“œμ˜ λ‘λ²ˆμ§Έ 인수둜 thisλ₯Ό μ „λ‹¬ν•˜κ±°λ‚˜ ES6의 ν™”μ‚΄ν‘œ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€.

forEach λ©”μ„œλ“œμ˜ 폴리필은 λ‹€μŒκ³Ό κ°™λ‹€.

🧐 폴리필

μ΅œμ‹  μ‚¬μ–‘μ˜ κΈ°λŠ₯을 μ§€μ›ν•˜μ§€ μ•ŠλŠ” λΈŒλΌμš°μ €λ₯Ό μœ„ν•΄ λˆ„λ½λœ μ΅œμ‹  μ‚¬μ–‘μ˜ κΈ°λŠ₯을 κ΅¬ν˜„ν•˜μ—¬ μΆ”κ°€ν•˜λŠ” 것을 폴리필이라 ν•œλ‹€.

// λ§Œμ•½ Array.prototype에 forEach λ©”μ„œλ“œκ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ©΄ 폴리필을 μΆ”κ°€ν•œλ‹€.
if (!Array.prototype.forEach) {
  Array.prototype.forEach = function (callback, thisArg) {
    // 첫 번째 μΈμˆ˜κ°€ ν•¨μˆ˜κ°€ μ•„λ‹ˆλ©΄ TypeErrorλ₯Ό λ°œμƒμ‹œν‚¨λ‹€.
    if (typeof callback !== 'function') {
      throw new TypeError(callback + ' is not a function');
    }
   // this둜 μ‚¬μš©ν•  두 번째 인수λ₯Ό 전달받지 λͺ»ν•˜λ©΄ μ „μ—­ 객체λ₯Ό this둜 μ‚¬μš©ν•œλ‹€.
    thisArg = thisArg || window;
    // for 문으둜 배열을 μˆœνšŒν•˜λ©΄μ„œ 콜백 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€.
    for (var i = 0; i < this.length; i++) {
      // call λ©”μ„œλ“œλ₯Ό 톡해 thisArgλ₯Ό μ „λ‹¬ν•˜λ©΄μ„œ 콜백 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€.
      // μ΄λ•Œ 콜백 ν•¨μˆ˜μ˜ 인수둜 λ°°μ—΄ μš”μ†Œ, 인덱슀, λ°°μ—΄ μžμ‹ μ„ μ „λ‹¬ν•œλ‹€.
      callback.call(thisArg, this[i], i, this);
    }
  };
}

forEach λ©”μ„œλ“œλŠ” forλ¬Έκ³ΌλŠ” 달리 break, continue 문을 μ‚¬μš©ν•  수 μ—†λ‹€. ν¬μ†Œ λ°°μ—΄μ˜ 경우 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” μš”μ†ŒλŠ” 순회 λŒ€μƒμ—μ„œ μ œμ™Έλœλ‹€.

[1, 2, 3].forEach(item => {
  console.log(item);
  if (item > 1) break; // SyntaxError: Illegal break statement
});
[1, 2, 3].forEach(item => {
  console.log(item);
  if (item > 1) continue;
  // SyntaxError: Illegal continue statement: no surrounding iteration statement
});
// ν¬μ†Œ λ°°μ—΄
const arr = [1, , 3];
// for 문으둜 ν¬μ†Œ 배열을 순회
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]); // 1, undefined, 3
}
// forEach λ©”μ„œλ“œλŠ” ν¬μ†Œ λ°°μ—΄μ˜ μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” μš”μ†Œλ₯Ό 순회 λŒ€μƒμ—μ„œ μ œμ™Έν•œλ‹€.
arr.forEach(v => console.log(v)); // 1, 3

βœ” 27.9.3 Array.prototype.map

map λ©”μ„œλ“œλŠ” μžμ‹ μ„ ν˜ΈμΆœν•œ λ°°μ—΄μ˜ λͺ¨λ“  μš”μ†Œλ₯Ό μˆœνšŒν•˜λ©΄μ„œ 인수둜 전달받은 콜백 ν•¨μˆ˜λ₯Ό 반볡 ν˜ΈμΆœν•˜κ³ , 콜백 ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’λ“€λ‘œ κ΅¬μ„±λœ μƒˆλ‘œμš΄ 배열을 λ°˜ν™˜ν•œλ‹€. μ΄λ•Œ 원본 배열은 λ³€κ²½λ˜μ§€ μ•ŠλŠ”λ‹€.

const numbers = [1, 4, 9];

// map λ©”μ„œλ“œλŠ” numbers λ°°μ—΄μ˜ λͺ¨λ“  μš”μ†Œλ₯Ό μˆœνšŒν•˜λ©΄μ„œ 콜백 ν•¨μˆ˜λ₯Ό 반볡 ν˜ΈμΆœν•œλ‹€.
// 그리고 콜백 ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’λ“€λ‘œ κ΅¬μ„±λœ μƒˆλ‘œμš΄ 배열을 λ°˜ν™˜ν•œλ‹€.
const roots = numbers.map(item => Math.sqrt(item));

// μœ„ μ½”λ“œλŠ” λ‹€μŒκ³Ό κ°™λ‹€.
// const roots = numbers.map(Math.sqrt);

// map λ©”μ„œλ“œλŠ” μƒˆλ‘œμš΄ 배열을 λ°˜ν™˜ν•œλ‹€
console.log(roots);   // [ 1, 2, 3 ]
// map λ©”μ„œλ“œλŠ” 원본 배열을 λ³€κ²½ν•˜μ§€ μ•ŠλŠ”λ‹€
console.log(numbers); // [ 1, 4, 9 ]

forEach λ©”μ„œλ“œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ map λ©”μ„œλ“œμ˜ 콜백 ν•¨μˆ˜λŠ” map λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄μ˜ μš”μ†Œκ°’κ³Ό 인덱슀, map λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄ 자체, 즉 thisλ₯Ό 순차적으둜 전달받을 수 μžˆλ‹€. λ‹€μ‹œ 말해, map λ©”μ„œλ“œλŠ” 콜백 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ 3개의 인수, 즉 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄μ˜ μš”μ†Œκ°’κ³Ό 인덱슀 그리고 map λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄(this)을 순차적으둜 μ „λ‹¬ν•œλ‹€.

// map λ©”μ„œλ“œλŠ” 콜백 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄μ„œ 3개(μš”μ†Œκ°’, 인덱슀, this)의 인수λ₯Ό μ „λ‹¬ν•œλ‹€.
[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]
*/

ν™”μ‚΄ν‘œ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•΄ add λ©”μ„œλ“œ λ‚΄λΆ€μ˜ thisλ₯Ό κ·ΈλŒ€λ‘œ μ°Έμ‘°ν• μˆ˜μžˆλ‹€.

class Prefixer {
  constructor(prefix) {
    this.prefix = prefix;
  }

  add(arr) {
    // ν™”μ‚΄ν‘œ ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ thisλ₯Ό μ°Έμ‘°ν•˜λ©΄ μƒμœ„ μŠ€μ½”ν”„μ˜ thisλ₯Ό κ·ΈλŒ€λ‘œ μ°Έμ‘°ν•œλ‹€.
    return arr.map(item => this.prefix + item);
  }
}

const prefixer = new Prefixer('-webkit-');
console.log(prefixer.add(['transition', 'user-select']));
// ['-webkit-transition', '-webkit-user-select']

βœ” 27.9.4 Array.prototype.filter

filter λ©”μ„œλ“œλŠ” μžμ‹ μ„ ν˜ΈμΆœν•œ λ°°μ—΄μ˜ λͺ¨λ“  μš”μ†Œλ₯Ό μˆœνšŒν•˜λ©΄μ„œ 인수둜 전달받은 콜백 ν•¨μˆ˜λ₯Ό 반볡 ν˜ΈμΆœν•œλ‹€. 그리고 콜백 ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μ΄ true인 μš”μ†Œλ‘œλ§Œ κ΅¬μ„±λœ μƒˆλ‘œμš΄ 배열을 λ°˜ν™˜ν•œλ‹€. μ΄λ•Œ 원본 배열은 λ³€κ²½λ˜μ§€ μ•ŠλŠ”λ‹€.

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, map λ©”μ„œλ“œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ filter λ©”μ„œλ“œλŠ” μžμ‹ μ„ ν˜ΈμΆœν•œ λ°°μ—΄μ˜ λͺ¨λ“  μš”μ†Œλ₯Ό μˆœνšŒν•˜λ©΄μ„œ 인수둜 전달받은 콜백 ν•¨μˆ˜λ₯Ό 반볡 ν˜ΈμΆœν•œλ‹€. forEach λ©”μ„œλ“œλŠ” μ–Έμ œλ‚˜ undefinedλ₯Ό λ°˜ν™˜ν•˜κ³ , map λ©”μ„œλ“œλŠ” 콜백 ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’λ“€λ‘œ κ΅¬μ„±λœ μƒˆλ‘œμš΄ 배열을 λ°˜ν™˜ν•˜μ§€λ§Œ filter λ©”μ„œλ“œλŠ” 콜백 ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μ΄ true인 μš”μ†Œλ§Œ μΆ”μΆœν•œ μƒˆλ‘œμš΄ 배열을 λ°˜ν™˜ν•œλ‹€.

forEach, map λ©”μ„œλ“œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ filter λ©”μ„œλ“œμ˜ 콜백 ν•¨μˆ˜λŠ” filter λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄μ˜ μš”μ†Œκ°’κ³Ό 인덱슀, filter λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄ 자체, 즉 thisλ₯Ό 순차적으둜 전달받을 수 있고, ν™”μ‚΄ν‘œ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•΄ this둜 μ‚¬μš©ν•  객체λ₯Ό 전달할 수 μžˆλ‹€.

filter λ©”μ„œλ“œλŠ” μžμ‹ μ„ ν˜ΈμΆœν•œ λ°°μ—΄μ—μ„œ νŠΉμ •μš”μ†Œλ₯Ό μ œκ±°ν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•  μˆ˜λ„ μžˆλ‹€. filter λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•΄ νŠΉμ • μš”μ†Œλ₯Ό μ œκ±°ν•  경우 νŠΉμ • μš”μ†Œκ°€ μ€‘λ³΅λ˜μ–΄ μžˆλ‹€λ©΄ μ€‘λ³΅λœ μš”μ†Œκ°€ λͺ¨λ‘ μ œκ±°λœλ‹€. νŠΉμ • μš”μ†Œλ₯Ό ν•˜λ‚˜λ§Œ μ œκ±°ν•˜λ €λ©΄ indexOf λ©”μ„œλ“œλ₯Ό 톡해 νŠΉμ • μš”μ†Œμ˜ 인덱슀λ₯Ό μ·¨λ“ν•œ λ‹€μŒ splice λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•œλ‹€.

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

βœ” 27.9.5 Array.prototype.reduce

reduce λ©”μ„œλ“œλŠ” μžμ‹ μ„ ν˜ΈμΆœν•œ 배열을 λͺ¨λ“  μš”μ†Œλ₯Ό μˆœνšŒν•˜λ©° 인수둜 전달받은 콜백 ν•¨μˆ˜λ₯Ό 반볡 ν˜ΈμΆœν•œλ‹€. 그리고 콜백 ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μ„ λ‹€μŒ 순회 μ‹œμ— 콜백 ν•¨μˆ˜μ˜ 첫 번째 인수둜 μ „λ‹¬ν•˜λ©΄μ„œ 콜백 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ—¬ ν•˜λ‚˜μ˜ 결과값을 λ§Œλ“€μ–΄ λ°˜ν™˜ν•œλ‹€. μ΄λ•Œ 원본 배열은 λ³€κ²½λ˜μ§€ μ•ŠλŠ”λ‹€.

reduce λ©”μ„œλ“œλŠ” 첫 번째 인수둜 콜백 ν•¨μˆ˜, 두 번째 인수둜 μ΄ˆκΈ°κ°’μ„ μ „λ‹¬λ°›λŠ”λ‹€. reduce λ©”μ„œλ“œμ˜ 콜백 ν•¨μˆ˜μ—λŠ” 4개의 인수, μ΄ˆκΈ°κ°’ λ˜λŠ” 콜백 ν•¨μˆ˜μ˜ 이전 λ°˜ν™˜κ°’, reduce λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄μ˜ μš”μ†Œκ°’κ³Ό 인덱슀, reduce λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄ 자체, 즉 thisκ°€ μ „λ‹¬λœλ‹€.

// [1, 2, 3, 4]의 λͺ¨λ“  μš”μ†Œμ˜ λˆ„μ μ„ κ΅¬ν•œλ‹€.
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
  • μ΅œλŒ€κ°’ κ΅¬ν•˜κΈ° (Math.maxκ°€ 더 직관적이닀)
    const values = [1, 2, 3, 4, 5];
    
    const max = values.reduce((acc, cur) => (acc > cur ? acc : cur), 0);
    console.log(max); // 5
    
    const values = [1, 2, 3, 4, 5];
    
    const max = Math.max(...values);
    // var max = Math.max.apply(null, values);
    console.log(max); // 5
  • μš”μ†Œμ˜ 쀑볡 횟수 κ΅¬ν•˜κΈ°
    const fruits = ['banana', 'apple', 'orange', 'orange', 'apple'];
    
    const count = fruits.reduce((acc, cur) => {
      // 첫 번째 순회 μ‹œ accλŠ” μ΄ˆκΈ°κ°’μΈ {}이고 cur은 첫 번째 μš”μ†ŒμΈ 'banana'λ‹€.
      // μ΄ˆκΈ°κ°’μœΌλ‘œ 전달받은 빈 객체에 μš”μ†Œκ°’μΈ cur을 ν”„λ‘œνΌν‹° ν‚€λ‘œ, μš”μ†Œμ˜ 개수λ₯Ό ν”„λ‘œνΌν‹° κ°’μœΌλ‘œ
      // ν• λ‹Ήν•œλ‹€. λ§Œμ•½ ν”„λ‘œνΌν‹° 값이 undefined(처음 λ“±μž₯ν•˜λŠ” μš”μ†Œ)이면 ν”„λ‘œνΌν‹° 값을 1둜 μ΄ˆκΈ°ν™”ν•œλ‹€.
      acc[cur] = (acc[cur] || 0) + 1;
      return acc;
    }, {});
    
    // 콜백 ν•¨μˆ˜λŠ” 총 5번 호좜되고 λ‹€μŒκ³Ό 같이 결과값을 λ°˜ν™˜ν•œλ‹€.
    /*
    {banana: 1} => {banana: 1, apple: 1} => {banana: 1, apple: 1, orange: 1}
    => {banana: 1, apple: 1, orange: 2} => {banana: 1, apple: 2, orange: 2}
    */
    
    console.log(count); // { banana: 1, apple: 2, orange: 2 }
  • 쀑첩 λ°°μ—΄ 평탄화 (Array.prototype.flat λ©”μ„œλ“œκ°€ 더 직관적이닀)
    const values = [1, [2, 3], 4, [5, 6]];
    
    const flatten = values.reduce((acc, cur) => acc.concat(cur), []);
    // [1] => [1, 2, 3] => [1, 2, 3, 4] => [1, 2, 3, 4, 5, 6]
    
    console.log(flatten); // [1, 2, 3, 4, 5, 6]
    
    [1, [2, 3, 4, 5]].flat(); // -> [1, 2, 3, 4, 5]
    
    // 인수 2λŠ” 쀑첩 배열을 ν‰νƒ„ν™”ν•˜κΈ° μœ„ν•œ 깊이 값이닀.
    [1, [2, 3, [4, 5]]].flat(2); // -> [1, 2, 3, 4, 5]
  • 쀑볡 μš”μ†Œ 제거 (Set 집합이 더 직관적이닀)
    const values = [1, 2, 1, 3, 5, 4, 5, 3, 4, 4];
    
    const result = values.reduce(
      (unique, val, i, _values) =>
        // ν˜„μž¬ 순회 쀑인 μš”μ†Œμ˜ 인덱슀 iκ°€ val의 μΈλ±μŠ€μ™€ κ°™λ‹€λ©΄ val은 처음 μˆœνšŒν•˜λŠ” μš”μ†Œλ‹€.
        // ν˜„μž¬ 순회 쀑인 μš”μ†Œμ˜ 인덱슀 iκ°€ val의 μΈλ±μŠ€μ™€ λ‹€λ₯΄λ‹€λ©΄ val은 μ€‘λ³΅λœ μš”μ†Œλ‹€.
        // 처음 μˆœνšŒν•˜λŠ” μš”μ†Œλ§Œ μ΄ˆκΈ°κ°’ []κ°€ μ „λ‹¬λœ unique 배열에 λ‹΄μ•„ λ°˜ν™˜ν•˜λ©΄ μ€‘λ³΅λœ μš”μ†ŒλŠ” μ œκ±°λœλ‹€.
        _values.indexOf(val) === i ? [...unique, val] : unique,
      []
    );
    
    console.log(result); // [1, 2, 3, 5, 4]
    
    const values = [1, 2, 1, 3, 5, 4, 5, 3, 4, 4];
    
    // 쀑볡을 ν—ˆμš©ν•˜μ§€ μ•ŠλŠ” Set 객체의 νŠΉμ„±μ„ ν™œμš©ν•˜μ—¬ λ°°μ—΄μ—μ„œ μ€‘λ³΅λœ μš”μ†Œλ₯Ό μ œκ±°ν•  수 μžˆλ‹€.
    const result = [...new Set(values)];
    console.log(result); // [1, 2, 3, 5, 4]
    reduce λ©”μ„œλ“œμ˜ 두 번째 인수인 μ΄ˆκΈ°κ°’μ€ μƒλž΅ κ°€λŠ₯ν•˜λ‚˜, μ „λ‹¬ν•˜λŠ”κ²ƒμ΄ μ•ˆμ „ν•˜λ‹€.

βœ” 27.9.6 Array.prototype.some

some λ©”μ„œλ“œλŠ” μžμ‹ μ„ ν˜ΈμΆœν•œ λ°°μ—΄μ˜ μš”μ†Œλ₯Ό μˆœνšŒν•˜λ©΄μ„œ 인수둜 μ „λ‹¬λœ 콜백 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€. μ΄λ•Œ some λ©”μ„œλ“œλŠ” 콜백 ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μ΄ 단 ν•œλ²ˆμ΄λΌλ„ 참이면 true, λͺ¨λ‘ 거짓이면 falseλ₯Ό λ°˜ν™˜ν•œλ‹€.

forEach, map, filter λ©”μ„œλ“œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ some λ©”μ„œλ“œμ˜ 콜백 ν•¨μˆ˜λŠ” some λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄μ˜ μš”μ†Œκ°’κ³Ό 인덱슀, filter λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄ 자체, 즉 thisλ₯Ό 순차적으둜 전달받을 수 있고, ν™”μ‚΄ν‘œ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•΄ this둜 μ‚¬μš©ν•  객체λ₯Ό 전달할 수 μžˆλ‹€.

// λ°°μ—΄μ˜ μš”μ†Œ 쀑에 10보닀 큰 μš”μ†Œκ°€ 1개 이상 μ‘΄μž¬ν•˜λŠ”μ§€ 확인
[5, 10, 15].some(item => item > 10); // -> true

// λ°°μ—΄μ˜ μš”μ†Œ 쀑에 0보닀 μž‘μ€ μš”μ†Œκ°€ 1개 이상 μ‘΄μž¬ν•˜λŠ”μ§€ 확인
[5, 10, 15].some(item => item < 0); // -> false

// λ°°μ—΄μ˜ μš”μ†Œ 쀑에 'banana'κ°€ 1개 이상 μ‘΄μž¬ν•˜λŠ”μ§€ 확인
['apple', 'banana', 'mango'].some(item => item === 'banana'); // -> true

// some λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ 배열이 빈 배열인 경우 μ–Έμ œλ‚˜ falseλ₯Ό λ°˜ν™˜ν•œλ‹€.
[].some(item => item > 3); // -> false

βœ” 27.9.7 Array.prototype.every

every λ©”μ„œλ“œλŠ” μžμ‹ μ„ ν˜ΈμΆœν•œ λ°°μ—΄μ˜ μš”μ†Œλ₯Ό μˆœνšŒν•˜λ©΄μ„œ 인수둜 μ „λ‹¬λœ 콜백 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€. μ΄λ•Œ every λ©”μ„œλ“œλŠ” 콜백 ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μ΄ λͺ¨λ‘ 참이면 true, 단 ν•œλ²ˆμ΄λΌλ„ 거짓이면 falseλ₯Ό λ°˜ν™˜ν•œλ‹€.

forEach, map, filter λ©”μ„œλ“œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ every λ©”μ„œλ“œμ˜ 콜백 ν•¨μˆ˜λŠ” every λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄μ˜ μš”μ†Œκ°’κ³Ό 인덱슀, filter λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄ 자체, 즉 thisλ₯Ό 순차적으둜 전달받을 수 있고, ν™”μ‚΄ν‘œ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•΄ this둜 μ‚¬μš©ν•  객체λ₯Ό 전달할 수 μžˆλ‹€.

// λ°°μ—΄μ˜ λͺ¨λ“  μš”μ†Œκ°€ 3보닀 큰지 확인
[5, 10, 15].every(item => item > 3); // -> true

// λ°°μ—΄μ˜ λͺ¨λ“  μš”μ†Œκ°€ 10보닀 큰지 확인
[5, 10, 15].every(item => item > 10); // -> false

// every λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ 배열이 빈 배열인 경우 μ–Έμ œλ‚˜ trueλ₯Ό λ°˜ν™˜ν•œλ‹€.
[].every(item => item > 3); // -> true

βœ” 27.9.8 Array.prototype.find

find λ©”μ„œλ“œλŠ” μžμ‹ μ„ ν˜ΈμΆœν•œ λ°°μ—΄μ˜ μš”μ†Œλ₯Ό μˆœνšŒν•˜λ©΄μ„œ 인수둜 μ „λ‹¬λœ 콜백 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ—¬ 첫 번째 μš”μ†Œλ₯Ό λ°˜ν™˜ν•œλ‹€. 콜백 ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μ΄ true 인 μš”μ†Œκ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ undefinedλ₯Ό λ°˜ν™˜ν•œλ‹€.

forEach, map, filter λ©”μ„œλ“œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ find λ©”μ„œλ“œμ˜ 콜백 ν•¨μˆ˜λŠ” find λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄μ˜ μš”μ†Œκ°’κ³Ό 인덱슀, find λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄ 자체, 즉 thisλ₯Ό 순차적으둜 전달받을 수 있고, ν™”μ‚΄ν‘œ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•΄ this둜 μ‚¬μš©ν•  객체λ₯Ό 전달할 수 μžˆλ‹€.

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'}

// Array#filterλŠ” 배열을 λ°˜ν™˜ν•œλ‹€.
[1, 2, 2, 3].filter(item => item === 2); // -> [2, 2]

// Array#findλŠ” μš”μ†Œλ₯Ό λ°˜ν™˜ν•œλ‹€.
[1, 2, 2, 3].find(item => item === 2); // -> 2

βœ” 27.9.9 Array.prototype.findIndex

findIndex λ©”μ„œλ“œλŠ” μžμ‹ μ„ ν˜ΈμΆœν•œ λ°°μ—΄μ˜ μš”μ†Œλ₯Ό μˆœνšŒν•˜λ©΄μ„œ 인수둜 μ „λ‹¬λœ 콜백 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ—¬ λ°˜ν™˜κ°’μ΄ true인 첫 번째 μš”μ†Œμ˜ 인덱슀λ₯Ό λ°˜ν™˜ν•œλ‹€. 콜백 ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μ΄ true인 μš”μ†Œκ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ -1을 λ°˜ν™˜ν•œλ‹€.

forEach, map, filter λ©”μ„œλ“œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ findIndex λ©”μ„œλ“œμ˜ 콜백 ν•¨μˆ˜λŠ” findIndex λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄μ˜ μš”μ†Œκ°’κ³Ό 인덱슀, findIndex λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄ 자체, 즉 thisλ₯Ό 순차적으둜 전달받을 수 있고, ν™”μ‚΄ν‘œ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•΄ this둜 μ‚¬μš©ν•  객체λ₯Ό 전달할 수 μžˆλ‹€.

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

βœ” 27.9.10 Array.prototype.flatMap

flatMap λ©”μ„œλ“œλŠ” 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']

const arr = ['hello', 'world'];

// flatMap은 1λ‹¨κ³„λ§Œ ν‰νƒ„ν™”ν•œλ‹€.
arr.flatMap((str, index) => [index, [str, str.length]]);
// -> [[0, ['hello', 5]], [1, ['world', 5]]] => [0, ['hello', 5], 1, ['world', 5]]

// 평탄화 깊이λ₯Ό 지정해야 ν•˜λ©΄ flatMap λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ§€ 말고 map λ©”μ„œλ“œμ™€ flat λ©”μ„œλ“œλ₯Ό 각각 ν˜ΈμΆœν•œλ‹€.
arr.map((str, index) => [index, [str, str.length]]).flat(2);
// -> [[0, ['hello', 5]], [1, ['world', 5]]] => [0, 'hello', 5, 1, 'world', 5
profile
μ΄μ‚¬μ€‘μž…λ‹ˆλ‹€!🌟https://velog.io/@devkyoung2

0개의 λŒ“κΈ€

κ΄€λ ¨ μ±„μš© 정보