Created
July 13, 2019 08:02
-
-
Save john-yuan/be0dc5e56169177f69264b07b0b3e6a0 to your computer and use it in GitHub Desktop.
A function to parse object path in JSON.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Parse the property path string. | |
* | |
* @param {string} path The property path. | |
* @returns {string[]} Returns the array of path. | |
*/ | |
function parseObjectPath(path) { | |
var i = 0; | |
var l = path.length; | |
var ch; | |
var T_KEYWORD = 1; | |
var T_PROP_SQ = 2; // ['prop_name'] | |
var T_PROP_DQ = 3; // ["prop_name"] | |
var T_PROP_NO = 4; // [1] | |
var type = T_KEYWORD; | |
var keywords = []; | |
var keywordBuffer = []; | |
var oneOf = function (ch, str) { | |
var j = 0; | |
var c = str.charAt(j); | |
while (c) { | |
if (c === ch) { | |
return true; | |
} else { | |
j += 1; | |
c = str.charAt(j); | |
} | |
} | |
return false; | |
}; | |
var whitespace = function () { | |
while (i < l && oneOf(path.charAt(i), ' \r\n\t')) { | |
++i; | |
} | |
}; | |
var unexpected = function (ch) { | |
throw new SyntaxError('unexpected token: ' + ch + ' at pos ' + i); | |
}; | |
var read = function () { | |
return path.charAt(i); | |
}; | |
var flushKeyword = function () { | |
var k = keywordBuffer.length; | |
var c; | |
while (k--) { | |
c = keywordBuffer[k]; | |
if (oneOf(c, ' \t\r\n')) { | |
keywordBuffer.pop(); | |
} else { | |
break; | |
} | |
} | |
k = keywordBuffer.join(''); | |
k && keywords.push(k); | |
keywordBuffer = []; | |
}; | |
var readNumber = function () { | |
var num = []; | |
while (true) { | |
ch = read(); | |
if (oneOf(ch, '0123456789')) { | |
num.push(ch); | |
i += 1; | |
} else { | |
break; | |
} | |
if (i >= l) { | |
throw new SyntaxError('unexpected end'); | |
} | |
} | |
return parseInt(num.join(''), 10); | |
}; | |
var readString = function (qoute) { | |
var str = []; | |
while (true) { | |
ch = read(); | |
i += 1; | |
if (ch === '\\') { | |
ch = read(); | |
if (ch === qoute) { | |
str.push(ch); | |
i += 1; | |
} else if (ch === '\\') { | |
str.push(ch); | |
i += 1; | |
} | |
} else if (ch === qoute) { | |
break; | |
} else { | |
str.push(ch); | |
} | |
if (i >= l) { | |
throw new SyntaxError('unexpected end'); | |
} | |
} | |
return str.join(''); | |
}; | |
whitespace(); | |
ch = path.charAt(i); | |
if (ch === '.') { | |
unexpected(ch); | |
} | |
while (i < l) { | |
if (type === T_KEYWORD) { | |
ch = read(); | |
if (ch === '[') { | |
flushKeyword(); | |
i += 1; | |
whitespace(); | |
ch = read(); | |
if (ch === "'") { | |
i += 1; | |
type = T_PROP_SQ; | |
} else if (ch === '"') { | |
i += 1; | |
type = T_PROP_DQ; | |
} else if (ch === ']') { | |
unexpected(']'); | |
} else { | |
type = T_PROP_NO; | |
} | |
} else if (ch === '.') { | |
flushKeyword(); | |
i += 1; | |
whitespace(); | |
ch = read(); | |
if (oneOf(ch, '.[')) { | |
unexpected(ch); | |
} | |
} else { | |
keywordBuffer.push(ch); | |
i += 1; | |
} | |
} else if (type === T_PROP_SQ || type === T_PROP_DQ) { | |
keywords.push(readString(type === T_PROP_SQ ? "'" : '"')); | |
whitespace(); | |
ch = read(); | |
if (ch !== ']') { | |
unexpected(ch); | |
} | |
i += 1; | |
type = T_KEYWORD; | |
} else if (type === T_PROP_NO) { | |
keywords.push(readNumber()); | |
whitespace(); | |
ch = read(); | |
if (ch !== ']') { | |
unexpected(ch); | |
} | |
i += 1; | |
type = T_KEYWORD; | |
} | |
} | |
flushKeyword(); | |
return keywords; | |
} | |
// var keywords = parseObjectPath("['the-key-of-the-person-object'].skills[0][123123]"); | |
// console.log(keywords); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment