1년 전만 해도, JS의 고차 함수 중 하나인 reduce()
를 봤을 때 이해가 잘 안됐는데
요즘 과제 구현 연습을 하면서 다시 보니 진짜 꿀 메서드인 것 같다.
정말 편하게 데이터의 구조를 바꿀 수 있어서 앞으로 개발에도 잘 활용해봐야겠다.
/**
* 콜백의 최초 호출 때 accumulator와 currentValue는 다음 두 가지 값 중 하나를 가질 수 있습니다.
*
* 만약 reduce() 함수 호출에서 initialValue를 제공한 경우,
* accumulator는 initialValue와 같고 currentValue는 배열의 첫 번째 값과 같습니다.
*
* initialValue를 제공하지 않았다면,
* accumulator는 배열의 첫 번째 값과 같고 currentValue는 두 번째와 같습니다.
*/
const arr = [1, 2, 3, 4];
const initial = 0;
const sum = arr.reduce((acc, cur, index) => {
console.log(acc, cur, index);
return acc + cur;
});
console.log(sum);
// 객체에서 값 다룰 땐 초기값 주기
const initialValue = 0;
const objArr = [{ x: 1 }, { x: 2 }, { x: 3 }];
// const objSum = objArr.reduce((acc, cur) => acc + cur.x, initialValue);
// function 함수 형태로도 쓸 수 있음
const objSum = objArr.reduce(function(acc, cur) {
return acc + cur.x;
}, initialValue);
console.log(objSum);
// 중첩 배열 펼치기
const arr2 = [
[0, 1],
[2, 3],
[4, 5],
];
// const flatten = arr2.reduce((acc, cur) => cur.forEach(c => acc.push(c)), [])
// 위 함수가 오류나는 이유
// reduce 콜백함수는 항상 누적값을 반환해야 하는데, forEach는 undefined를 반환함
// 이렇게 acc를 반환해줘야 함
const flatten = arr2.reduce((acc, cur) => {
cur.forEach(c => acc.push(c))
return acc;
}, []);
// 또는 spread 연산자로 반환할 수 있음
const flatten2 = arr2.reduce((acc, cur) => [...acc, ...cur]);
// 또는 concat을 사용할 수도 있음
const flatten3 = arr2.reduce((acc, cur) => acc.concat(cur));
// 객체 내의 값 인스턴스 개수 세기
const names = ["Alice", "Bob", "Tiff", "Bruce", "Alice"];
const countedNames = names.reduce((obj, name) => {
if (Object.hasOwn(obj, name)) {
obj[name]++;
} else {
obj[name] = 1;
}
return obj;
}, {});
// 속성으로 객체 분류하기
const people = [
{ name: "Alice", age: 21 },
{ name: "Max", age: 20 },
{ name: "Jane", age: 20 },
];
// 나이에 따라 객체를 분류해보자
const classified = people.reduce((obj, cur) => {
if (Object.hasOwn(obj, cur.age)) {
obj[cur.age].push(cur.name);
} else {
obj[cur.age] = [];
obj[cur.age].push(cur.name);
}
return obj;
}, {});
// 확장 연산자와 초기값을 이용하여 객체로 이루어진 배열에 담긴 배열 연결하기
var friends = [
{
name: "Anna",
books: ["Bible", "Harry Potter"],
age: 21,
},
{
name: "Bob",
books: ["War and peace", "Romeo and Juliet"],
age: 26,
},
{
name: "Alice",
books: ["The Lord of the Rings", "The Shining"],
age: 18,
},
];
const allBooks = friends.reduce((allbooks, cur) => {
return [...allbooks, ...cur.books];
}, ["Alphabet"]);
console.log(allBooks);
// allBooks = [
// 'Alphabet', 'Bible', 'Harry Potter', 'War and peace',
// 'Romeo and Juliet', 'The Lord of the Rings',
// 'The Shining'
// ]
// 배열의 중복 항목 제거하기
const duplicateArr = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4];
const removedArr = duplicateArr.sort().reduce((newArr, cur) => {
if (!newArr.includes(cur)) newArr.push(cur);
return newArr;
}, []);
// Set으로 제거해보기
const removedSet = duplicateArr.sort().reduce((set, cur) => {
if (!set.has(cur)) set.add(cur);
return set;
}, new Set());
console.log([...removedSet]);