211110_개발자 준비하기(39일차) - 재귀함수로 Strigify, Menu list 구현

주형(Jureamer)·2022년 1월 4일
0
post-custom-banner

오늘 배운 것(끄적끄적)


  • 재귀함수로 JSON.Stringify 구현 JSON.stringify는 JSONJavascript Object Notation의 약자로 데이터 교환을 위해 만들어진 객체 형태의 포맷이다. JSON은 2개의 메소드만을 가지고 있다.
    • stringify: Object Type을 JSON으로 변환

    • parse: JSON을 Object Type으로 변환

      Untitled

      이것을 직렬화(Serialized → stringify), 역직렬화(Deserialized → parse)라고도 부른다.

    • JSON 기본규칙

      Untitled

    • 재귀함수를 이용한 JSON.stringify 코드 (미완성)

function stringifyJSON(obj) {
  // your code goes here
  if (typeof obj === "boolean" || typeof obj === "number" || obj === null) {
    return String(obj);
  }

  if (Array.isArray(obj)) {
    let resultArr = [];
    for (let i of obj) {
      // i가 배열인 경우와 아닌경우, 배열인 경우 재귀함수사용 아닐시 그대로 리턴
      let returnArr = [];
      if (!Array.isArray(i)) {
        // 배열이 아닌 경우
        if (typeof i === "string") {
          // 배열의 요소가 문자열인 경우
          resultArr.push(`"${i}"`);
        } else {
          // 배열의 요소가 문자열이 아닌 경우
          resultArr.push(`${i}`);
        }
      } else {
        // 배열인 경우
        returnArr = stringifyJSON(i); // 리턴시 반복문 종료
      }
      if (returnArr.length !== 0) {
        resultArr.push(returnArr);
      }
    }
    return `[${resultArr}]`; // 배열을 리턴했지만, 문자열 형태로 리턴됨.
  }

  if (typeof obj === "string") {
    return `"${obj}"`;
  }

  if (typeof obj === "object" && !Array.isArray(obj)) {
    let sumStr = "";
    let newObj = "";
    if (Object.keys(obj).length === 0) return "{}";

    for (let i = 0; i < Object.keys(obj).length; i++) {
      let returnObj = "";
      if (typeof Object.values(obj)[i] === "boolean" || Object.values(obj)[i] === null) {
        sumStr += `"${Object.keys(obj)[i]}":${Object.values(obj)[i]},`;
      } else if (typeof Object.values(obj)[i] === "object") {
        returnObj = stringifyJSON(Object.values(obj[i])); //{"b": "c"}
      } else {
        sumStr += `"${Object.keys(obj)[i]}":"${Object.values(obj)[i]}",`;
      }

      if (returnObj !== "") {
        sumStr += `"${Object.keys(obj)[i]}":${returnObj},`;
      }

      newObj = `{${sumStr.slice(0, sumStr.length - 1)}}`;
    }
    return newObj;
  }
}

여기까지 구현했는데 Object에서 재귀함수를 쓰는 부분에서 막혀버렸다. 자꾸 아래와 같은 오류가 뜬다.

TypeError: Cannot convert undefined or null to object
      at Function.values (<anonymous>)
      at stringifyJSON (src/stringifyJSON.js:74:42)
      at Context.<anonymous> (spec/stringifyJSONSpec.js:48:22)
      at processImmediate (node:internal/timers:464:21)

⇒ 이 오류는 Object.keys().length에서 Object값을 제대로 못넣어줘서 그렇게 된다고 하는데 난감하다,, 재귀함수에 된통 당해버렸다. 요것은 주말에 다시 복기하면서 완벽히 풀어 볼 예정이다.

  • tree UI 구현 tree UI 구현은 DOM 구조와 재귀함수를 이용해서 js에서 HTML로 메뉴 정보를 코딩하는 과제였다. JS와 DOM을 이용해서 HTML을 짜는 건 보다 직관적이어서 푸는 재미가 있었다. ** 많은 양을 append 시킬 때는 appendChild가 아니라 append를 통해서 한 번에 넣어버리자!
    
    const menu = [
      {
        type: "group",
        name: "음료",
        children: [
          {
            type: "group",
            name: "콜드 브루",
            children: [
              { type: "item", name: "나이트로 콜드 브루" },
              { type: "item", name: "돌체 콜드 브루" },
              { type: "item", name: "제주 비자림 콜드 브루" },
              { type: "item", name: "콜드 브루" },
            ],
          },
    
    //메뉴는 너무 길어 이정도에서 생략,, 음료와 같은 객체가 배열에 총 4개가 들어있다.
    
    const root = document.getElementById("root");
    
    function createTreeView(menu, currentNode) {
    
      // for문을 통해 menu 배열을 돌면서 name값을 li.textcontent
      // 자식 노드가 있는 데이터의 경우, li 엘리먼트 아래에 자식 노드를 렌더링할 새로운 
    	// ul이 존재해야 합니다
      let createChildNode;
      for (let i = 0; i < menu.length; i++) {
        const liMaker = document.createElement("li");
        currentNode.appendChild(liMaker);
    
        if (!menu[i].children) {
          liMaker.textContent = menu[i].name;
        } else {
          const spanMaker = document.createElement("span");
          const inputMaker = document.createElement("input");
          inputMaker.setAttribute("type", "checkbox");
          liMaker.appendChild(inputMaker);
          liMaker.appendChild(spanMaker);
          spanMaker.textContent = menu[i].name;
    
          const ulMaker = document.createElement("ul");
          liMaker.appendChild(ulMaker);
    
          createChildNode = createTreeView(menu[i].children, ulMaker);
        }
      }
    }
    
    createTreeView(menu, root);

    완성본

Untitled

느낀점


Tree-ui와 같이 실전에서 쓸법한 문제를 푸니까 어제보다는 재귀함수의 역할이 좀 더 와닿는 것 같았다. 특히 어려운 부분이 for문 안에서 재귀함수를 구현할 때 return 문으로 빼는게 아닌 변수로 값을 담아서 리턴을 해야하는데 이 부분이 풀려고 하는 문제마다 생각을 많이 요하는 부분이라 시간 소모가 많았다.

그래도!! 그만큼 성취감이 크게 주어졌다.

내일 배울 것


  • 자료구조
  • Stack, Queue, Tree, Graph, BST
  • 트리 및 그래프 탐색 기법
  • 자료구조를 활용한 알고리즘 문제 접근
profile
작게라도 꾸준히 성장하는게 목표입니다.
post-custom-banner

0개의 댓글