递归实现JSON.stringify

时间:2015-08-10 01:11:30

标签: javascript json recursion

对于作业,我试图以递归方式实现JSON.stringify功能。

但是,我当前的方法 - 尝试直接返回连接对象的键/值对的字符串 - 并不起作用,因为括号和逗号放错了位置。理想情况下,我将能够递归地构造一个数组,然后用逗号连接元素,但我不确定如何做到这一点。有任何建议或替代方法吗?

谢谢!

var stringifyJSON = function(obj) {
  if (typeof(obj) == "object") {
    var newValue;
    var objKeys = Object.keys(obj);
    if (Object.keys(obj).length === 0) {
      return "";
    }
    else if (Object.keys(obj).length !== 0) {
      var key = (typeof(objKeys[0]) == "string") ? '"' + objKeys[0] + '"' : objKeys[0];
      var value = (typeof(obj[objKeys[0]]) == "string") ? '"' + obj[objKeys[0]] + '"' : obj[objKeys[0]];
      newValue = key + ":" + value;
      delete obj[objKeys[0]];
    }
    return "{" + newValue + "," + stringifyJSON(obj) + "}";
  }
};

1 个答案:

答案 0 :(得分:0)

我以递归方式创建了 JSON.stringify() 方法的整个实现。您需要以不同的方式处理数组和对象,并根据数据类型进行递归。特别是对于最后一个逗号,您可以直接弹出它而无需任何额外的时间成本,这将帮助您不必担心在每个递归树上添加逗号。


const JSONStringify = (obj) => {

  const isArray = (value) => {
    return Array.isArray(value) && typeof value === 'object';
  };

  const isObject = (value) => {
    return typeof value === 'object' && value !== null && !Array.isArray(value);
  };

  const isString = (value) => {
    return typeof value === 'string';
  };

  const isBoolean = (value) => {
    return typeof value === 'boolean';
  };

  const isNumber = (value) => {
    return typeof value === 'number';
  };

  const isNull = (value) => {
    return value === null && typeof value === 'object';
  };

  const isNotNumber = (value) => {
    return typeof value === 'number' && isNaN(value);
  };

  const isInfinity = (value) => {
    return typeof value === 'number' && !isFinite(value);
  };

  const isDate = (value) => {
    return typeof value === 'object' && value !== null && typeof value.getMonth === 'function';
  };

  const isUndefined = (value) => {
    return value === undefined && typeof value === 'undefined';
  };

  const isFunction = (value) => {
    return typeof value === 'function';
  };

  const isSymbol = (value) => {
    return typeof value === 'symbol';
  };

  const restOfDataTypes = (value) => {
    return isNumber(value) || isString(value) || isBoolean(value);
  };

  const ignoreDataTypes = (value) => {
    return isUndefined(value) || isFunction(value) || isSymbol(value);
  };

  const nullDataTypes = (value) => {
    return isNotNumber(value) || isInfinity(value) || isNull(value);
  }

  const arrayValuesNullTypes = (value) => {
    return isNotNumber(value) || isInfinity(value) || isNull(value) || ignoreDataTypes(value);
  }

  const removeComma = (str) => {
    const tempArr = str.split('');
    tempArr.pop();
    return tempArr.join('');
  };


  if (ignoreDataTypes(obj)) {
    return undefined;
  }

  if (isDate(obj)) {
    return `"${obj.toISOString()}"`;
  }

  if(nullDataTypes(obj)) {
    return `${null}`
  }

  if(isSymbol(obj)) {
    return undefined;
  }


  if (restOfDataTypes(obj)) {
    const passQuotes = isString(obj) ? `"` : '';
    return `${passQuotes}${obj}${passQuotes}`;
  }

  if (isArray(obj)) {
    let arrStr = '';
    obj.forEach((eachValue) => {
      arrStr += arrayValuesNullTypes(eachValue) ? JSONStringify(null) : JSONStringify(eachValue);
      arrStr += ','
    });

    return  `[` + removeComma(arrStr) + `]`;
  }

  if (isObject(obj)) {
      
    let objStr = '';

    const objKeys = Object.keys(obj);

    objKeys.forEach((eachKey) => {
        const eachValue = obj[eachKey];
        objStr +=  (!ignoreDataTypes(eachValue)) ? `"${eachKey}":${JSONStringify(eachValue)},` : '';
    });
    return `{` + removeComma(objStr) + `}`;
  }
};

这是链接:https://javascript.plainenglish.io/create-your-own-implementation-of-json-stringify-simiplied-version-8ab6746cdd1