재귀를 이용해 메소드 JSON.stringify 구현하기

🐶·2021년 6월 16일
6

미니 과제

목록 보기
4/15

재귀를 이용해 메소드 JSON.stringify를 함수의 형태로 직접 구현해보았다. 인풋으로 여러 타입의 데이터가 들어오는데, 어떤 조건에서 재귀 호출하면 좋을지 고민해보았다.

1. Broswer에 존재하는 JSON.stringfy 함수를 직접구현해봅니다.
JSON.stringfy 함수는 input 값을 JSON 형식으로 변환합니다.
단, undefind와 function은 JSON으로 생략되거나 null 로 변환됩니다.

2. stringfyJSON은 아래와 같이 작동합니다.
- Bolean이 input으로 주어졌을 경우
stringifyJSON(true);                // 'true'
- String이 input으로 주어졌을 경우
stringifyJSON('foo');               // '"foo"'
- Array가 input으로 주어졌을 경우
stringifyJSON([1, 'false', false]); // '[1,"false",false]' // 
- Object가 input으로 주어졌을 경우
stringifyJSON({ x: 5 });            // '{"x":5}'
- undefind, function이 주어졌을 경우
stringifyJSON(undefined)            // undefined
stringifyJSON(function(){})         // undefined
stringifyJSON({ x: undefined, y: function(){} })   // '{}'

코드 풀이 과정

  1. 인풋이 boolean, number, null인 경우(null은 typeof를 씌웠을 때 'object'로 나오기 때문에 obj === null이라고 조건을 걸어줬다)
if(typeof obj ==='boolean' || typeof obj ==='number' || obj === null){
    return String(obj)
  }
  1. undefined와 function인 경우
if(typeof obj ==='undefined' ||typeof obj ==='function'){
    return 'undefined';
  }
  1. string인 경우
  if(typeof obj ==='string'){
    return `"${obj}"`
  }
  1. array인 경우,
    모든 배열의 요소를 순회한다. 배열의 요소를 재귀함수의 전달인자로 넣고 리턴값을 새로운 빈 배열에다가 push해준다.
if(Array.isArray(obj)){
    let newArr = []; 
    for(let item of obj){
        newArr.push(stringifyJSON(item)) //push만 해주고 
    }  
    return `[${newArr}]` //`${newArr}` 하면 요소만 나열되고 통째로 문자열 
  }
  1. 인풋이 object인 경우,
    객체의 속성을 훑으면서
  • 객체의 속성 값이 function or undefined인 경우:{} 빈 객체 리턴
  • key와 value 값을 각각 재귀함수의 전달인자로 넣어주고 새로운 빈 문자열에다가 누적하여 이어주었다
if(typeof obj ==='object' && obj!==null){//typeof ==='object' 1, object, 2, array, 3. null,--> 2, 3번 제외
    let str = '';
      for (let key in obj) {
        if (typeof obj[key]==='function' || obj[key] === undefined) {
          return "{}";
        }
        let newKey = stringifyJSON(key); //key
        let newValue = stringifyJSON(obj[key]);//key의 값
        str = str+ newKey + ":" + newValue+',';
      }
      str = str.slice(0, -1); //마지막 쉼표 버리기
      return `{${str}}`;
  } 

코드를 종합해보면

function stringifyJSON(obj) {
  
  if(typeof obj ==='boolean' || typeof obj ==='number' || obj === null){
    return String(obj)
  }
  if(typeof obj ==='string'){
    return `"${obj}"`
  }
  if(typeof obj ==='undefined' ||typeof obj ==='function'){
    return 'undefined';
  }

  if(Array.isArray(obj)){
    let newArr = []; //push메소드 쓰지 않고 배열의 요소를 stringifyJSON(item)값으로 치환할 때도 구현 가능
    for(let item of obj){
        newArr.push(stringifyJSON(item)) //push만 해주고 
    } 
    return `[${newArr}]` //`${newArr}` 하면 요소만 나열되고 통째로 문자열 
  }

  if(typeof obj ==='object' && obj!==null){
    let str = '';
      for (let key in obj) {
        if (typeof obj[key]==='function' || obj[key] === undefined) {
          return "{}";
        }
        let newKey = stringifyJSON(key); //key
        let newValue = stringifyJSON(obj[key]);//key의 값
        str = str+ newKey + ":" + newValue+',';
      }
      str = str.slice(0, -1); //마지막 쉼표 버리기
      return `{${str}}`;
  } 
};

초반에는 이런저런 경우의 수를 복잡하게 조건으로 나열하느라 진땀뺐지만, 문제의 의도를 파악하고 다시 풀어보니 수월하게 해결할 수 있었다.

profile
우당탕탕 개발일기📝🤖

0개의 댓글