Skip to content

Instantly share code, notes, and snippets.

@hlfbt
Last active February 22, 2017 15:28
Show Gist options
  • Save hlfbt/f2d3dee06d8af6ad35caaa48927e5f32 to your computer and use it in GitHub Desktop.
Save hlfbt/f2d3dee06d8af6ad35caaa48927e5f32 to your computer and use it in GitHub Desktop.
Searches through an object for an identifier
/*
* Recurses through an object to search for an identifier.
* Identifier is a RegExp.
* Returns either the first match or false.
*/
function search (obj, term) {
for (var k in obj) {
if (obj.hasOwnProperty(k)) {
if (k == term) return k;
if (typeof obj[k] in ['string', 'number'] && ''.match.call(obj[k], term)) return k + '.' + obj[k];
if (typeof obj[k] == 'object') {
var s = search(obj[k], term);
if (typeof s == 'string') return '' + k + '.' + s;
}
}
}
return false;
}
/*
* This one doesn't quite work properly yet, but should detect reference loops and handles hitting the maximum stack size
*/
function search (obj, term, maxDepth, verb, trace) {
if (typeof verb === 'undefined') verb = true;
if (!maxDepth) maxDepth = 50;
if (!trace) trace = [];
else if (trace.length >= maxDepth) {
if (verb) {
var n = '';
for (var t in trace) n += '.' + trace[t][0];
console.error("Max depth hit at: " + n.substr(1));
}
return -2;
}
else {
if (trace.length > 9) {
var unique = trace.slice(-10).reduce(function (a, b) { return ((a.includes(b[0]) || a.push(b[0])), a); }, []);
if (unique.length < 6 && unique.slice(-1)[0] === trace.slice(-1)[0][0]) {
if (verb) {
var n = '';
for (var t in trace) n += '.' + trace[t][0];
console.error("Possible recursive reference detected: " + n.substr(1));
}
return -1;
}
}
}
for (var k in obj) {
if (obj.hasOwnProperty(k)) {
try {
if (k.match(term)) return k;
if (typeof obj[k] in ['string', 'number'] && ''.match.call(obj[k], term)) return k + '.' + obj[k];
if (typeof obj[k] == 'object') {
trace.push([k, obj[k]]);
var s = search(obj[k], term, verb, trace);
if (typeof s == 'string') return '' + k + '.' + s;
if (s < 0) return s + 1;
}
} catch (e) {
if (e.message.match('Maximum call stack size exceeded$')) {
if (verb) {
var n = '';
for (var t in trace) n += '.' + trace[t][0];
console.error('Call stack limit reached at: ' + n.substr(1) + '.' + k);
return false;
} else throw e;
}
}
}
}
return false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment