博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何以类似JSON的格式打印圆形结构?
阅读量:2290 次
发布时间:2019-05-09

本文共 6211 字,大约阅读时间需要 20 分钟。

本文翻译自:

I have a big object I want to convert to JSON and send. 我有一个大对象,想要转换为JSON并发送。 However it has circular structure. 但是它具有圆形结构。 I want to toss whatever circular references exist and send whatever can be stringified. 我想抛弃任何存在的循环引用,并发送任何可以字符串化的内容。 How do I do that? 我怎么做?

Thanks. 谢谢。

var obj = {  a: "foo",  b: obj}

I want to stringify obj into: 我想将obj字符串化为:

{"a":"foo"}

#1楼

参考:


#2楼

Use JSON.stringify with a custom replacer. JSON.stringify与自定义JSON.stringify一起使用。 For example: 例如:

// Demo: Circular referencevar circ = {};circ.circ = circ;// Note: cache should not be re-used by repeated calls to JSON.stringify.var cache = [];JSON.stringify(circ, function(key, value) {    if (typeof value === 'object' && value !== null) {        if (cache.indexOf(value) !== -1) {            // Duplicate reference found, discard key            return;        }        // Store value in our collection        cache.push(value);    }    return value;});cache = null; // Enable garbage collection

The replacer in this example is not 100% correct (depending on your definition of "duplicate"). 在此示例中,替换器并非100%正确(取决于您对“重复”的定义)。 In the following case, a value is discarded: 在以下情况下,将丢弃一个值:

var a = {b:1}var o = {};o.one = a;o.two = a;// one and two point to the same object, but two is discarded:JSON.stringify(o, ...);

But the concept stands: Use a custom replacer, and keep track of the parsed object values. 但是概念仍然存在:使用自定义替换器,并跟踪已解析的对象值。


#3楼

Use the JSON.stringify method with a replacer. 将JSON.stringify方法与替换器一起使用。 Read this documentation for more information. 阅读此文档以获取更多信息。

var obj = {  a: "foo",  b: obj}var replacement = {"b":undefined};alert(JSON.stringify(obj,replacement));

Figure out a way to populate the replacement array with cyclic references. 找出一种使用循环引用填充替换数组的方法。 You can use the typeof method to find if an the property is of type 'object' ( reference ) and an exact equality check ( === ) to verify circular reference. 您可以使用typeof方法查找属性是否为'object'类型(引用),并使用精确相等性检查(===)来验证循环引用。


#4楼

For future googlers searching for a solution to this problem when you don't know the keys of all circular references, you could use a wrapper around the JSON.stringify function to rule out circular references. 对于将来的Google员工,当您知道所有循环引用的键时都在寻找解决方案,可以使用JSON.stringify函数周围的包装器来排除循环引用。 See an example script at . 请参阅的示例脚本。

The solution essentially boils down to keeping a reference to previously printed objects in an array, and checking that in a replacer function before returning a value. 解决方案本质上可以归结为保留对数组中先前打印的对象的引用,并在返回值之前在替换函数中进行检查。 It's more constrictive than only ruling out circular references, because it also rules out ever printing an object twice, one of the side affects of which is to avoid circular references. 它比仅排除循环引用更为严格,因为它还排除了两次打印对象的副作用,其中之一是避免使用循环引用。

Example wrapper: 包装器示例:

function stringifyOnce(obj, replacer, indent){    var printedObjects = [];    var printedObjectKeys = [];    function printOnceReplacer(key, value){        var printedObjIndex = false;        printedObjects.forEach(function(obj, index){            if(obj===value){                printedObjIndex = index;            }        });        if(printedObjIndex && typeof(value)=="object"){            return "(see " + value.constructor.name.toLowerCase() + " with key " + printedObjectKeys[printedObjIndex] + ")";        }else{            var qualifiedKey = key || "(empty key)";            printedObjects.push(value);            printedObjectKeys.push(qualifiedKey);            if(replacer){                return replacer(key, value);            }else{                return value;            }        }    }    return JSON.stringify(obj, printOnceReplacer, indent);}

#5楼

I really liked Trindaz's solution - more verbose, however it had some bugs. 我真的很喜欢Trindaz的解决方案-更详细,但是有一些错误。 I fixed them for whoever likes it too. 我为喜欢的人固定了它们。

Plus, I added a length limit on my cache objects. 另外,我在缓存对象上增加了长度限制。

If the object I am printing is really big - I mean infinitely big - I want to limit my algorithm. 如果我要打印的对象真的很大-我的意思是无限大-我想限制我的算法。

JSON.stringifyOnce = function(obj, replacer, indent){    var printedObjects = [];    var printedObjectKeys = [];    function printOnceReplacer(key, value){        if ( printedObjects.length > 2000){ // browsers will not print more than 20K, I don't see the point to allow 2K.. algorithm will not be fast anyway if we have too many objects        return 'object too long';        }        var printedObjIndex = false;        printedObjects.forEach(function(obj, index){            if(obj===value){                printedObjIndex = index;            }        });        if ( key == ''){ //root element             printedObjects.push(obj);            printedObjectKeys.push("root");             return value;        }        else if(printedObjIndex+"" != "false" && typeof(value)=="object"){            if ( printedObjectKeys[printedObjIndex] == "root"){                return "(pointer to root)";            }else{                return "(see " + ((!!value && !!value.constructor) ? value.constructor.name.toLowerCase()  : typeof(value)) + " with key " + printedObjectKeys[printedObjIndex] + ")";            }        }else{            var qualifiedKey = key || "(empty key)";            printedObjects.push(value);            printedObjectKeys.push(qualifiedKey);            if(replacer){                return replacer(key, value);            }else{                return value;            }        }    }    return JSON.stringify(obj, printOnceReplacer, indent);};

#6楼

In Node.js, you can use . 在Node.js中,可以使用 。 It automatically replaces circular links with "[Circular]". 它会自动将圆形链接替换为“ [Circular]”。


Albeit being built-in (no installation is required) , you must import it 尽管是内置的(无需安装) ,但必须将其导入

import * as util from 'util' // has no default exportimport { inspect } from 'util' // or directly// or var util = require('util')
To use it, simply call
要使用它,只需调用
inspect(myObject[, options: {showHidden, depth, colors, showProxy, ...moreOptions}])

Also be aware that you can pass options object to inspect (see link above) 另外请注意,您可以通过options对象进行检查(请参见上面的链接)

inspect(myObject[, options: {showHidden, depth, colors, showProxy, ...moreOptions}])


Please, read and give kudos to commenters below... 请阅读下面的评论并将其赞扬...

转载地址:http://incnb.baihongyu.com/

你可能感兴趣的文章
logback的使用和logback.xml详解
查看>>
Linux 快捷键
查看>>
JPA 联合主键配置
查看>>
ObjectAlreadyExistsException:Unable to store Job : '*', because one already exists with thi s ident
查看>>
这些大厂面试真题你能答出来,年薪至少30-50W,想不想挑战一下?
查看>>
携程T7用637页PDF,解读十余热门技术领域,八场携程技术沙龙干货
查看>>
开发框架SpringBoot:构建SpringBoot工程+配置文件详解+Actuator
查看>>
6年拉力工作经验,学了阿里P8级架构师的7+1+1落地项目,跳槽阿里年薪直接40W+
查看>>
90天吃透阿里P8推荐的625页Java编程兵书技术实战,直接入职阿里定级P6
查看>>
清华毕业扫地僧,用157集终于把java给讲完了,总计3.13GB
查看>>
清华毕业大佬用了一个项目就把SpringMVC+Spring+MyBatis给讲完了
查看>>
终于学完阿里P8架构师多年实战经验总结分享微服务之道实战文档
查看>>
年薪120W的架构师简历你见过吗?java程序员该如何达到?
查看>>
超赞!80W美团架构师7年心血终成轻量级框架SSM整合开发实战文档
查看>>
超赞!终于学完了阿里P8架构师7年心血整理总结的微服务实战文档
查看>>
真666!阿里资深架构师熬夜纯手写的238页微服务容器化开发实战笔记
查看>>
终于学完了2021年阿里内部480道全套java面试题及答案
查看>>
面试官:熟悉Redis吗,项目中你是如何对Redis内存进行优化的
查看>>
JVM 实战学习总结:JVM 的分代模型:年轻代、老年代、永久代
查看>>
面试官:聊聊 Spring 中的线程安全性
查看>>