Skip to content

Instantly share code, notes, and snippets.

@simonwep
Created May 19, 2019 10:40
Show Gist options
  • Save simonwep/3f0f432ecf1d052c526b664377a218ed to your computer and use it in GitHub Desktop.
Save simonwep/3f0f432ecf1d052c526b664377a218ed to your computer and use it in GitHub Desktop.
const lookUpObjectValue = (obj, str) => {
const validProp = c => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c === '_';
const isNum = c => c >= '0' && c <= '9';
const errored = i => {
const cursor = `${str}\n${' '.repeat(i)}^`;
console.error(`Invalid accessor:\n${cursor}`);
};
const length = str.length;
for (let i = 0; i < length; i++) {
const ch = str[i];
if (validProp(ch)) {
let consumed = ch;
for (; validProp(str[i + 1]) || isNum(str[i + 1]);
consumed += str[++i]) ;
obj = obj[consumed];
} else if (ch === '[') {
const next = str[++i];
// Resolve string or index
if (next === '\'' || next === '"') {
i++;
let consumed = '';
for (; str[i] !== next || str[i - 1] === '\\';
consumed += str[i++]) ;
obj = obj[consumed];
i++;
} else {
let consumed = next;
for (; isNum(str[i + 1]);
consumed += str[++i]) ;
const parsed = Number(consumed || NaN);
if (str[++i] === ']' && !isNaN(parsed)) {
obj = obj[parsed];
} else {
return errored(i);
}
}
} else if (isNum(ch)) {
return errored(i);
} else {
continue;
}
if (i !== length - 1 && str[i + 1] !== '.' && str[i + 1] !== '[') {
return errored(i);
}
}
return obj;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment