[JS] 고차함수 reduce 실습 예제

김성현·6일 전
0

MDN 문서 - Reduce()

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]);
profile
만드는 거 좋아하는 개발자

0개의 댓글