Last active
August 29, 2015 14:05
-
-
Save gionkunz/6d42acb21e9ec44fbc05 to your computer and use it in GitHub Desktop.
JSON generator with circular reference censoring
This file contains 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
function flatten(s, stack) { | |
if(s === undefined || s === null || (typeof s === 'number' && isNaN(s))) { | |
return 'null'; | |
} else if(s instanceof Date) { | |
return flatten(s.toJSON(), stack); | |
} else if(typeof s === 'object') { | |
stack = stack ? {obj: s, parent: stack} : {obj: s}; | |
if((function cyclic(obj, stack, found) { | |
return found || | |
(stack.parent ? cyclic(obj, stack.parent, stack.parent.obj === obj) : false); | |
}(s, stack))) { | |
return flatten('[circular reference]'); | |
} else if(s instanceof Array) { | |
return ['[', s.map(function(v) { | |
return flatten(v, stack); | |
}).join(','), ']'].join(''); | |
} else { | |
return ['{', Object.keys(s).filter(function(key) { | |
return s[key] !== undefined; | |
}).map(function(key) { | |
return ['"', key, '"', ':', flatten(s[key], stack)].join(''); | |
}).join(','), '}'].join(''); | |
} | |
} else if (typeof s === 'string') { | |
return ['"', s, '"'].join(''); | |
} else { | |
return s; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
After I didn't find a satisfying solution to compare simple data objects, and I've found that comparing JSON strings is a very simple and nice way to compare simple data structures, I came up with this solution to generate JSON while sanitizing circular references. I found existing solutions with object re-occurrence checks not ideal as they don't take into account the object hierarchy. This solution is keeping track of the "call stack" with a stack object during the recursive calls and tracing back to parent stacks for circular reference detection.
You can play around with this function here: http://jsbin.com/hefis/3/edit
I did not check the JSON.stringify implementations and therefore don't know if I missed something in the conversion process. Please comment if you have any suggestions.