본문 바로가기
자바스크립트

[JAVASCRIPT] 중첩 객체에서 특정 프로퍼티의 합 구하기, 재귀함수 활용

by jaewooojung 2021. 8. 19.

JAVASCRIPT


중첩 객체에서 프로퍼티의 합 구하기

코딩 테스트에서 자주 활용되는 개념입니다. 간단해 보이지만 의외로 헤매는 경우가 많습니다.

 

아래와 같은 타입을 가지는 product 객체가 있다고 가정합니다.

name: string;
price: number;

 

products 객체에는 product들이 아래와 같이 여러 중첩 객체로 포함되어 있습니다.

const products = {
  fruits: [
    {
      name: "apple",
      price: 1000,
    },
    {
      name: "banana",
      price: 2000,
    },
  ],
  clothes: {
    bottom: [
      {
        name: "jean",
        price: 3000,
      },
    ],
    top: {
      shirts: [
        {
          name: "blue shirt",
          price: 3500,
        },
        {
          name: "red shirt",
          price: 3800,
        },
      ],
      jakets: [
        {
          name: "blue jaket",
          price: 6000,
        },
        {
          name: "red jacket",
          price: 6300,
        },
      ],
    },
  },
};

 

 

여기서 모든 product의 price의 합을 재귀적인 방법으로 구해보겠습니다.

 

1.

products를 파라미터로 받는 함수의 뼈대입니다.

function sumPrice(category) {

}

sumPrice(products);

 

 

2.

if 구문으로 전달된 파라미터가 배열인지 확인합니다.

function sumPrice(category) {
  if (Array.isArray(category)) {
	// 프로퍼티가 배열인 경우 - 중첩객체 없음
  } else {
  	// 프로퍼티가 객체인 경우 - 중첩객체
  }
}

sumPrice(products);

 

2-1. 배열인 경우

더 이상 중첩객체가 없으며, 배열을 순회하면서 각 요소의 price값에 접근할 수 있습니다. 이 부분은 더 이상 함수를 호출하지 않고 계산된 값을 반환하는 재귀함수의 base가 됩니다.

function sumPrice(category) {
  if (Array.isArray(category)) {
    let sum = 0;
    category.forEach((product) => {
      sum += product.price;
    });
    return sum;
  } else {
    // 프로퍼티가 객체인 경우 - 중첩객체
  }
}

sumPrice(products);

 

 

reduce 함수를 사용하면 간단하게 작성할 수 있습니다.

function sumPrice(category) {
  if (Array.isArray(category)) {
    return category.reduce((prev, current) => prev + current.price, 0);
  } else {
    // 프로퍼티가 객체인 경우 - 중첩객체
  }
}

sumPrice(products);

 

 

2-2. 객체인 경우

price값을 확인할 수 없기 때문에 배열이 나올 때까지 함수(자기 자신)를 호출해야 합니다.

 

Object.values 메서드와 for... of 구문을 활용해 객체의 프로퍼티들을 순회하며 다시 함수를 호출합니다. 함수의 호출은 배열이 나올 때까지 반복되며, 배열이 나오면 재귀의 base 코드가 실행되면서 sum의 값을 역순으로 가산합니다.

function sumPrice(category) {
  if (Array.isArray(category)) {
    return category.reduce((prev, current) => prev + current.price, 0);
  } else {
    let sum = 0;
    for (const subCategory of Object.values(category)) {
      sum += sumPrice(subCategory);
    }
    return sum;
  }
}

sumPrice(products);

 

결과

console.log(sumPrice(products)); // 25600
console.log(sumPrice(products.clothes)); // 22600
console.log(sumPrice(products.fruits)); // 3000


        
답변을 생성하고 있어요.