对于作业,我试图以递归方式实现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) + "}";
}
};
答案 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) + `}`;
}
};