Skip to content

Instantly share code, notes, and snippets.

@jochemstoel
Forked from dmitrythaler/JSON.replacer.js
Created January 30, 2019 22:35
Show Gist options
  • Save jochemstoel/520b496e988063313f4d067c096e1bb0 to your computer and use it in GitHub Desktop.
Save jochemstoel/520b496e988063313f4d067c096e1bb0 to your computer and use it in GitHub Desktop.
replacer function for the JSON.stringify() with depth and duplicates control
const replacer = function( depth = Number.MAX_SAFE_INTEGER ) {
let objects, stack, keys;
return function(key, value) {
// very first iteration
if (key === '') {
keys = ['root'];
objects = [{keys: 'root', value: value}];
stack = [];
return value;
}
// From the JSON.stringify's doc: "The object in which the key was found is
// provided as the replacer's this parameter."
// Thus one can control the depth
while ( stack.length && this !== stack[0] ) {
stack.shift();
keys.pop();
}
// console.log( keys.join('.') );
let type = typeof value;
if ( type === 'boolean' || type === 'number' || type === 'string' ) {
return value;
}
if ( type === 'function' ) {
return `[Function, ${value.length + 1} args]`;
}
if (value === null) {
return 'null';
}
if (!value) {
return undefined;
}
if (stack.length >= depth ) {
if ( Array.isArray(value) ) {
return `[Array(${value.length})]`;
}
return '[Object]';
}
let found = objects.find( o => o.value === value );
if ( !found ) {
keys.push( key );
stack.unshift( value );
objects.push({keys: keys.join('.'), value: value});
return value;
}
// actually, here's the only place where the keys keeping is useful
return `[Duplicate: ${found.keys}]`;
};
};
// Usage
console.log( JSON.stringify( someObject, replacer(2), 2 ) );
console.log( JSON.stringify( someObject, replacer(), 2 ) );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment