限制JSON字符串化深度

时间:2013-05-09 16:07:10

标签: javascript json stringify

使用JSON.stringify(或类似的东西)对对象进行字符串化时,有一种方法可以限制字符串化深度,即只将 n 级别深入到对象树中并忽略所有来的之后(或更好:在那里放置占位符,表明遗漏了什么)?

我知道JSON.stringify采用function (key, value)形式的替换函数,但是我没有找到一种方法来获取当前键值对的原始对象的深度。替代品功能。

有没有办法使用默认的JSON.stringify实现?或者我已经达到了我应该自己实现字符串化的程度? 或者是否有另一个可以推荐的具有此选项的字符串化库?

3 个答案:

答案 0 :(得分:7)

我想在第一层对字符串进行字符串化,而不包括第三方库/太多代码。

如果您要查找相同内容,请执行以下快速单行程序:

var json = JSON.stringify(obj, function (k, v) { return k ? "" + v : v; });

示例:

var obj = {
  keyA: "test",
  keyB: undefined,
  keyC: 42,
}
obj.keyD = obj;

var json = JSON.stringify(obj, function (k, v) { return k ? "" + v : v; });
console.log(json);

通过在值之前添加空字符串,它会自动将值转换为字符串。但是,当元素为null或未定义时,我们需要检查键以确保不要强制转换。

答案 1 :(得分:1)

对您的对象进行深度克隆(使用诸如low-dash之类的库),执行您想要修剪的内容,然后将其传递给JSON.stringify。我不会尝试重新发明JSON.stringify,这是在错误的地方努力。

[编辑] 看起来有人已经做了你的建议:JSON.stringify deep objects

我不推荐这个,因为原生的JSON.stringify总是更快更强大

[编辑] 这里有一个似乎可以做你想要的库:http://philogb.github.io/jit/static/v20/Docs/files/Core/Core-js.html# $ jit.json.prune

答案 2 :(得分:0)

这是一个尊重内置JSON.stringify()规则同时限制深度的功能:

function stringify(val, depth, replacer, space) {
    depth = isNaN(+depth) ? 1 : depth;
    function _build(key, val, depth, o, a) { // (JSON.stringify() has it's own rules, which we respect here by using it for property iteration)
        return !val || typeof val != 'object' ? val : (a=Array.isArray(val), JSON.stringify(val, function(k,v){ if (a || depth > 0) { if (replacer) v=replacer(k,v); if (!k) return (a=Array.isArray(v),val=v); !o && (o=a?[]:{}); o[k] = _build(k, v, a?depth:depth-1); } }), o||{});
    }
    return JSON.stringify(_build('', val, depth), null, space);
}

工作原理:

    递归调用
  1. _build()来将嵌套的对象和数组构建到请求的深度。 JSON.stringify()用于遍历每个对象的直接属性以遵守内置规则。始终从内部替换器返回“ undefined”,因此实际上尚未构造任何JSON。请记住,第一次调用内部替换器时,密钥为空(这是要字符串化的项目)。
  2. 在最终结果上调用
  3. JSON.stringify()来生成实际的JSON。

示例:

var value={a:[12,2,{y:3,z:{q:1}}],s:'!',o:{x:1,o2:{y:1}}};

console.log(stringify(value, 0, null, 2));
console.log(stringify(value, 1, null, 2));
console.log(stringify(value, 2, null, 2));

{}

{
  "a": [
    12,
    2,
    {}
  ],
  "s": "!",
  "o": {}
}

{
  "a": [
    12,
    2,
    {
      "y": 3,
      "z": {}
    }
  ],
  "s": "!",
  "o": {
    "x": 1,
    "o2": {}
  }
}

(有关处理循环引用的版本,请参见此处:https://stackoverflow.com/a/57193345/1236397-包括TypeScript版本)