Back to all solutions
#2759 - Convert JSON String to Object
Problem Description
Given a string str, return parsed JSON parsedStr. You may assume the str is a valid JSON string hence it only includes strings, numbers, arrays, objects, booleans, and null. str will not include invisible characters and escape characters.
Please solve it without using the built-in JSON.parse method.
Solution
/**
* @param {string} str
* @return {null|boolean|number|string|Array|Object}
*/
var jsonParse = function(str) {
const length = str.length;
const stack = [];
let currentValue = null;
let pendingKey = null;
for (let index = 0; index < length; index++) {
if (str[index] === ',') continue;
if (str[index] === '[' || str[index] === '{') {
stack.push(currentValue);
let newContainer = null;
if (str[index] === '[') newContainer = [];
else newContainer = {};
if (Array.isArray(currentValue)) currentValue.push(newContainer);
else if (pendingKey !== null) {
currentValue[pendingKey] = newContainer;
pendingKey = null;
}
currentValue = newContainer;
} else if (str[index] === ']' || str[index] === '}') {
const previousValue = stack.pop();
if (index !== length - 1) currentValue = previousValue;
} else {
let parsedValue = null;
if (str[index] === '"') {
const startIndex = index + 1;
while (index + 1 < length && str[index + 1] !== '"') index++;
parsedValue = str.substring(startIndex, index + 1);
index++;
} else if (str[index] === '-' || ('0' <= str[index] && str[index] <= '9')) {
const startIndex = index;
while (index + 1 < length && (str[index + 1] === '-'
|| ('0' <= str[index + 1] && str[index + 1] <= '9') || str[index + 1] === '.')) {
index++;
}
parsedValue = Number(str.substring(startIndex, index + 1));
} else {
if (index + 4 <= length && str.substring(index, index + 4) === 'true') {
parsedValue = true;
} else if (index + 5 <= length && str.substring(index, index + 5) === 'false') {
parsedValue = false;
} else {
parsedValue = null;
}
index += parsedValue || parsedValue === null ? 3 : 4;
}
if (str[index + 1] === ':') {
pendingKey = parsedValue;
index++;
} else if (Array.isArray(currentValue)) {
currentValue.push(parsedValue);
} else if (pendingKey !== null) {
currentValue[pendingKey] = parsedValue;
pendingKey = null;
} else {
currentValue = parsedValue;
}
}
}
return currentValue;
};