Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

자바스크립트 재귀 함수로 JSON 객체를 label-children 트리 구조로 변환하기

다음과 같이 중첩된 JSON 객체가 있다고 가정해 보겠습니다.

const obj = {
   "context": {
      "device": {
         "localeCountryCode": "AX",
         "datetime": "3047-09-29T07:09:52.498Z"
      },
      "currentLocation": {
         "country": "KM",
         "lon": -78789486
    }
};

우리의 과제는 위와 같은 객체를 입력으로 받아, 각 속성을 "label""children" 형태의 계층 구조로 변환하는 자바스크립트 재귀 함수를 작성하는 것입니다. 값이 또 다른 객체라면 하위 노드(children)로 재귀적으로 탐색하고, 문자열이나 숫자처럼 더 이상 중첩되지 않은 값이라면 label만 가진 리프 노드로 처리하면 됩니다.

따라서 위 객체를 변환한 최종 결과물은 다음과 같은 형태가 되어야 합니다.

const output = {
   "label": "context",
   "children": [
      {
         "label": "device",
         "children": [
         {
            "label": "localeCountryCode"
         },
         {
            "label": "datetime"
         }
      ]
   },
   {
      "label": "currentLocation",
      "children": [
            {
               "label": "country"
            },
            {
               "label": "lon"
            }
         ]
      }
   ]
}

구현 코드

핵심 아이디어는 간단합니다. 객체의 모든 키를 순회하면서, 해당 키의 값이 객체인지 확인한 뒤 객체라면 자기 자신을 다시 호출하여 children을 만들고, 아니라면 label만 반환하는 방식입니다.

const obj = {
   "context": {
      "device": {
         "localeCountryCode": "AX",
         "datetime": "3047-09-29T07:09:52.498Z"
      },
      "currentLocation": {
         "country": "KM",
         "lon": -78789486
    }
};

const transformObject = (obj = {}) => {
   if (obj && typeof obj === 'object') {
      return Object.keys(obj).map((el) => {
         let children = transformObject(obj[el]);
         return children ? { label: el, children: children } : { label: el };
      });
   }
};

console.log(JSON.stringify(transformObject(obj), undefined, 4));

코드 동작 방식

이 함수의 로직을 단계별로 살펴보면 다음과 같습니다.

1. 재귀 종료 조건: 전달된 값이 객체가 아닌 경우(문자열, 숫자 등 원시 값)에는 undefined를 반환하며 재귀를 멈춥니다.
2. 키 순회: Object.keys()로 객체의 모든 키를 추출한 뒤 map()으로 하나씩 처리합니다.
3. 재귀 호출: 각 키의 값을 다시 transformObject()에 넘겨, 그 결과가 존재하면 { label, children } 형태의 노드를 만들고, 없다면 { label }만 반환합니다.

실행 결과

위 코드를 실행하면 콘솔에 다음과 같이 출력됩니다.

[
   {
      "label": "context",
      "children": [
         {
            "label": "device",
            "children": [
               {
                  "label": "localeCountryCode"
               },
               {
               "label": "datetime"
               }
            ]
         },
         {
            "label": "currentLocation",
            "children": [
                  {
                     "label": "country"
                  },
                  {
                     "label": "lon"
                  }
               ]
            }
      ]
   }
]

이처럼 재귀 함수를 활용하면 깊이에 상관없이 임의의 중첩 구조를 가진 JSON 객체도 일관된 트리 형태로 손쉽게 변환할 수 있습니다. 이 기법은 파일 탐색기, 카테고리 메뉴, 조직도처럼 계층 데이터를 UI로 렌더링해야 할 때 특히 유용하게 활용됩니다.