Skip to content

Instantly share code, notes, and snippets.

@ilazarte
Last active May 14, 2017 06:38
Show Gist options
  • Save ilazarte/8676179 to your computer and use it in GitHub Desktop.
Save ilazarte/8676179 to your computer and use it in GitHub Desktop.
/**
* Cycle detection function
* Outputs count and grouped cycles with a from key path and to key path.
* The executing browser should have console.group and .groupEnd functions.
*
* Based on:
* http://stackoverflow.com/questions/14962018/detecting-and-fixing-circular-references-in-javascript/14962496#14962496
*
* @param {Object} obj Any js object
* @return {void}
*/
function detect(obj) {
var i = 0, nodes = [], cycles = [], cycle;
function search(val) {
var i = 0, node;
for (; i < nodes.length; i++) {
node = nodes[i];
if (node.obj === val) {
return node;
}
}
return false;
}
function conj(arr, key) {
var narr = [].concat(arr);
narr.push(key);
return narr;
}
function walk(obj, keys) {
var key, res;
if (typeof obj !== 'object') { return; }
res = search(obj);
if (res) {
cycles.push({
from: keys,
to: res.keys,
obj: obj
});
} else {
nodes.push({obj:obj, keys:keys});
for (key in obj) {
if (obj.hasOwnProperty(key)) {
walk(obj[key], conj(keys, key));
}
}
}
}
walk(obj, []);
console.log("\nobj has " + cycles.length + " cycle(s)");
for(; i < cycles.length; i++) {
cycle = cycles[i];
console.group("idx: " + i);
console.log(JSON.stringify(cycle.from) + ' to ' + JSON.stringify(cycle.to));
/*console.log(cycle.obj);*/
console.groupEnd();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment