Front-end/JS

μžλ°”μŠ€ν¬λ¦½νŠΈ λ°°μ—΄ κ³ μ°¨ν•¨μˆ˜ reduce

ciocio 2021. 8. 15. 11:50

πŸ“  Array.prototype.reduce ( immutable )

 

 

reduce λ©”μ„œλ“œλŠ” μžμ‹ μ„ ν˜ΈμΆœν•œ 배열을 λͺ¨λ“  μš”μ†Œλ₯Ό μˆœνšŒν•˜λ©° 인수둜 전달받은 μ½œλ°±ν•¨μˆ˜λ₯Ό 반볡 ν˜ΈμΆœν•œλ‹€.

그리고 콜백 ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μ„ λ‹€μŒ 순회 μ‹œμ— 콜백 ν•¨μˆ˜μ˜ 첫번째 인수둜 μ „λ‹¬ν•˜λ©΄μ„œ 콜백 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ—¬,

ν•˜λ‚˜μ˜ 결과값을 λ§Œλ“€μ–΄ λ°˜ν™˜ν•œλ‹€.

 

// 1λΆ€ν„° 4κΉŒμ§€ λˆ„μ μ„ κ΅¬ν•œλ‹€.
// 숫자끼리 값을 더할 λ•ŒλŠ” μ΄ˆκΈ°κ°’μ„ 0으둜 μ„€μ •ν•˜μ§€ μ•Šμ•„λ„ 값이 λ‚˜μ˜€μ§€λ§Œ
// κ·Έλž˜λ„! κ·Έλž˜λ„! μ΄ˆκΈ°κ°’μ„ λ„£μ–΄μ£ΌλŠ” 게 μ’‹λ‹€.

const sum = [1, 2, 3, 4].reduce(
  // 콜백 ν•¨μˆ˜
  (accumulator, currentvalue, index, array) => {
    accumulator + currentvalue
  },
// μ΄ˆκΈ°κ°’
0);

console.log(sum);  // 10

 

πŸ””  reduce λ©”μ„œλ“œλŠ” μ΅œλŒ€ 2개의 인수λ₯Ό 받을 수 μžˆλ‹€.

 

01  콜백 ν•¨μˆ˜

02  μ΄ˆκΈ°κ°’

 

 

πŸ””  reduce λ©”μ„œλ“œμ˜ μ½œλ°±ν•¨μˆ˜λŠ” μ΅œλŒ€ 4개의 인수λ₯Ό 받을 수 μžˆλ‹€.

 

01  μ΄ˆκΈ°κ°’ or 콜백 ν•¨μˆ˜μ˜ 이전 λ°˜ν™˜κ°’

02  reduce λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄μ˜ μš”μ†Œκ°’

03  reduce λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄μ˜ 인덱슀

04  reduce λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ°°μ—΄ 자체 ( this )

 

 

 

🏁  평균 κ΅¬ν•˜κΈ°

 

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

 

 

 

 

 

 

 

 

 

 

 

별닀λ₯Έ 객체가 없어도 { length } 에

λ°°μ—΄μ˜ 길이가 λ‹΄κ²¨μžˆλŠ” κ±Έ 확인할 수 μžˆλ‹€ wow...

 

 

 

 

 

 

 

 

 

🏁  μ΅œλŒ€κ°’ κ΅¬ν•˜κΈ°

 

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

const max = values.reduce((acc, cur) => (acc > cur ? acc : cur), 0);

console.log(max);  // 5

// κ·Έλ ‡μ§€λ§Œ ... μ΅œλŒ€κ°’μ„ ꡬ할 λ•ŒλŠ” reduce λ©”μ„œλ“œλ³΄λ‹€ ❗Math.max λ©”μ„œλ“œβ—κ°€ 더 μ§κ΄€μ μž„

let max1 = Math.max(...values);
// let max1 = Math.max.apply(null, values);

console.log(max);  // 5

 

 

 

 

 

 

 

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;
}, {});

 

 

 

acc κ°€ 콜백 ν•¨μˆ˜μž„μ„ μ—¬μ‹€νžˆ λ³΄μ—¬μ£ΌλŠ” λΆ€λΆ„

 

 

 

 

 

β—Ύ 논리 μ—°μ‚°μž ' || ' 정체 

 

논리 OR ( expr1 || expr2 )

expr1을 true둜 λ°˜ν™˜ν•  수 있으면 expr1을 λ°˜ν™˜ν•œλ‹€.

κ·Έ μ™Έμ˜ κ²½μš°μ—λŠ” expr2λ₯Ό λ°˜ν™˜ν•œλ‹€.

λΆˆλ¦¬μ–Έ κ°’κ³Ό ν•¨κ»˜ μ‚¬μš©ν•œ κ²½μš°μ—λŠ” ν•˜λ‚˜λΌλ„ 참이면 trueλ₯Ό, κ·Έ μ™Έμ—λŠ” falseλ₯Ό λ°˜ν™˜ν•œλ‹€.

 

 

 

 

🏁  쀑첩 λ°°μ—΄ 평탄화

 

const values = [1, [2, 3], 4, [5, 6]];
// concat은 μ΄λ ‡κ²Œ 2쀑 λ°°μ—΄κΉŒμ§€λ§Œ 벗겨낼 수 μžˆλ‹€. κ·Έ 이상은 μ•ˆλŒ

const flatten = values.reduce((acc, cur) => acc.concat(cur), []);

console.log(flatten);  // [1, 2, 3, 4, 5, 6]

// κ·Έλ ‡μ§€λ§Œ !! 쀑첩 배열을 평탄화할 λ•ŒλŠ” reduce λ©”μ„œλ“œλ³΄λ‹€ ❗flat λ©”μ„œλ“œβ—κ°€ 더 μ§κ΄€μ μž„

[1, [2, 3, 4, 5]].flat();  // [1, 2, 3, 4, 5]
[1, [2, 3, [4, 5]]].flat(2);  // [1, 2, 3, 4, 5]
// 인수 2λŠ” 쀑첩 배열을 ν‰νƒ„ν™”ν•˜κΈ° μœ„ν•œ 깊이 값이닀 wow 정말 νŽΈλ¦¬ν•˜λ‹€ wow

 

 

 

🏁  쀑볡 μš”μ†Œ 제거

 

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

const result = values.reduce((acc, cur, i, arr) => {
  // 순회 쀑인 μš”μ†Œμ˜ 첫 μΈλ±μŠ€κ°€ μžμ‹ μ˜ 인덱슀라면, 처음 μˆœνšŒν•˜λŠ” μš”μ†Œλ‹€.
  // 이 μš”μ†Œλ§Œ μ΄ˆκΈ°κ°’μœΌλ‘œ 전달받은 배열에 λ‹΄μ•„ λ°˜ν™˜ν•œλ‹€.
  // 순회 쀑인 μš”μ†Œμ˜ 첫 μΈλ±μŠ€κ°€ μžμ‹ μ˜ μΈλ±μŠ€κ°€ μ•„λ‹ˆλΌλ©΄ μ€‘λ³΅λœ μš”μ†Œλ‹€.
  if(arr.indexOf(cur) === i) acc.push(cur);
  return acc;
}, []);

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

// κ·Έλ ‡μ§€λ§Œ !! 쀑볡 μš”μ†Œλ₯Ό μ œκ±°ν•  λ•ŒλŠ” reduce λ©”μ„œλ“œλ³΄λ‹€ ❗filter λ©”μ„œλ“œβ—κ°€ 더 μ§κ΄€μ μž„

const result = values.filter((v, i, arr) => arr.indexOf(v) === i);

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

// λ˜λŠ” ! μ€‘λ³΅λ˜μ§€ μ•ŠλŠ” μœ μΌν•œ κ°’λ“€μ˜ 집합인 ❗Set❗을 μ‚¬μš©ν•  μˆ˜λ„ 있음
// 쀑볡 μš”μ†Œλ₯Ό μ œκ±°ν•  땐, 이 방법을 μΆ”μ²œμΆ”μ²œ ?ㅁ<

const result1 = [...new Set(values)];

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

indexOf( ) λ©”μ„œλ“œλ‹ˆκΉŒ 이게 κ°€λŠ₯ν•œκ±°λ‹€ ~!~!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

❗ reduce λ©”μ„œλ“œ ν˜ΈμΆœν•  λ•Œ μ£Όμ˜ν•  점

❗ μ–Έμ œλ‚˜ μ΄ˆκΈ°κ°’μ„ μ „λ‹¬ν•˜λŠ” 것이 μ•ˆμ „ν•˜λ‹€.

 

// reduce λ©”μ„œλ“œμ˜ 두 번째 인수, 즉 μ΄ˆκΈ°κ°’μ„ μƒλž΅ν•¨

const sum = [1, 2, 3, 4].reduce((acc,cur) => acc + cur);
console.log(sum);  // 10

 

κ·Έλž˜λ„ μ›ν•˜λŠ” κ°’이 λ‚˜μ˜€κΈ΄ λ‚˜μ˜¨λ‹€. ν•˜μ§€λ§Œ κ²½μš°μ˜ μˆ˜κ°€ ν•œμ •μ μž„.

 

const sum1 = [].reduce((acc, cur) => acc + cur);
// Uncaught TypeError: Reduce of empty array with no initial value

 

μ΄ˆκΈ°κ°’μ„ μ„€μ •ν•˜μ§€ μ•ŠμœΌλ©΄ μ΄λ ‡κ²Œ μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

 

const sum2 = [].reduce((acc, cur) => acc + cur, 0);
console.log(sum);  // 0

 

μ΄ˆκΈ°κ°’μ„ μ„€μ •ν•˜λ©΄ μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•Šκ³ , μ›ν•˜λŠ” 값이 λ‚˜μ˜¨λ‹€.

 

 

 

❗ 이건 λ‚΄κ°€ μ•Œκ³ λ¦¬μ¦˜ 문제λ₯Ό ν’€λ©΄μ„œλ„ λΆ€λ”ͺ쳀던 λΆ€λΆ„ ❗

 

 

 

 

 

 

 

 

 

 

이건 되고 μ™œ 저건 μ•ˆλ˜λ‚˜ κ³ λ―Όν–ˆλ˜ λΆ€λΆ„ γ…œγ…œ

ν•΄μ†Œλ˜μ—ˆλ”° !!

 

 

 

 

 

 

 

 

 

const products = [
  { id: 1, price: 100 },
  { id: 2, price: 200 },
  { id: 3, price: 300 }
];

const priceSum = products.reduce((acc, cur) => acc.price + cur.price);

// 첫번째 순회 : accλŠ” { id: 1, price: 100 }, cur은 { id: 2, price: 200 }이닀.
// λ‘λ²ˆμ§Έ 순회 : accλŠ”          300         , cur은 { id: 3, price: 300 }이닀.
// λ‘λ²ˆμ§Έ 순회 : acc에 ν•¨μˆ˜ 객체가 μ•„λ‹Œ μˆ«μžκ°’μ΄ μ „λ‹¬λœλ‹€. μ΄λ•Œ acc.priceλŠ” undefinedλ‹€.

console.log(priceSum);  // NaN

 

이처럼 ❗객체 ν”„λ‘œνΌν‹° 값을 ν•©μ‚°ν•˜λŠ” κ²½μš°β—μ—λŠ” λ°˜λ“œμ‹œ μ΄ˆκΈ°κ°’μ„ μ „λ‹¬ν•΄μ•Όν•œλ‹€.

λ¬Όλ‘  κ·Έ 외에도 μ΄ˆκΈ°κ°’ κΌ­κΌ­ μ μ–΄μ£Όμž ⭐⭐⭐

 

const products = [
  { id: 1, price: 100 },
  { id: 2, price: 200 },
  { id: 3, price: 300 }
];

const priceSum = products.reduce((acc, cur) => acc + cur.price, 0);

// 첫번째 순회 : accλŠ”   0 , cur은 { id: 1, price: 100 }이닀.
// λ‘λ²ˆμ§Έ 순회 : accλŠ”  100, cur은 { id: 2, price: 200 }이닀.
// λ‘λ²ˆμ§Έ 순회 : accλŠ”  300, cur은 { id: 3, price: 300 }이닀.

console.log(priceSum);  // 600
λ°˜μ‘ν˜•