Skip to content

Instantly share code, notes, and snippets.

@bennettmcelwee
Last active November 19, 2022 09:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bennettmcelwee/06f0cadd6a41847f848b4bd2a351b6bc to your computer and use it in GitHub Desktop.
Save bennettmcelwee/06f0cadd6a41847f848b4bd2a351b6bc to your computer and use it in GitHub Desktop.
Version of JSON.stringify limitied to a specific depth.
// Similar to JSON.stringify but limited to a specified depth (default 1)
// The approach is to prune the object first, then just call JSON.stringify to do the formatting
const prune = (obj, depth = 1) => {
if (Array.isArray(obj) && obj.length > 0) {
return (depth === 0) ? ['???'] : obj.map(e => prune(e, depth - 1))
} else if (obj && typeof obj === 'object' && Object.keys(obj).length > 0) {
return (depth === 0) ? {'???':''} : Object.keys(obj).reduce((acc, key) => ({ ...acc, [key]: prune(obj[key], depth - 1)}), {})
} else {
return obj
}
}
const stringify = (obj, depth = 1, space) => JSON.stringify(prune(obj, depth), null, space)
@sturmenta
Copy link

const stringify = (obj: any, depth = 1): string => {
  return !obj
    ? JSON.stringify(obj, null, 2)
    : typeof obj === 'object'
    ? JSON.stringify(
        JSON.parse(
          depth < 1
            ? '"???"'
            : `{${Object.keys(obj)
                .map((k) => `"${k}": ${stringify(obj[k], depth - 1)}`)
                .join(', ')}}`,
        ),
        null,
        2,
      )
    : JSON.stringify(obj, null, 2);
};

working with null, 2 format in typescript

@bennettmcelwee
Copy link
Author

bennettmcelwee commented Feb 9, 2022

Thanks for the update! I actually wrote it to use in the browser console, so can't really use TS. But your more modern code is much better (and your bug fix) :-)

I have completely changed it now anyway: I decided that I should just create a clone of the object, pruned to the right depth; and then just call JSON.stringify to do the formatting.

@WyrdNexus
Copy link

Thank you @bennettmcelwee and @sturmenta. I've adapted sturmenta's code back into native js, cleaned it up a bit, and added handling for undefined. Should be fairly efficient and robust now, as well as being easily adjusted to needs.

function stringifyMaxDepth (obj, depth = 1) {
    // recursion limited by depth arg
    if (!obj || typeof obj !== 'object') return JSON.stringify(obj)

    let curDepthResult = '"<?>"' // too deep
    if (depth > 0) {
        curDepthResult = Object.keys(obj)
            .map( (key) => {
                let val = stringifyMaxDepth(obj[key], depth - 1)
                if (val === undefined) val = 'null'
                return `"${key}": ${val}`
            })
            .join(', ')
        curDepthResult = `{${curDepthResult}}`
    }

    return JSON.stringify(JSON.parse(curDepthResult))
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment