解决来自JSON对象的循环引用

如果我从json.net获得序列化的JSON,如下所示:


User:{id:1,{Foo{id:1,prop:1}},

FooList{$ref: "1",Foo{id:2,prop:13}}

我想让淘汰赛在FooList上输出foreach,但是我不确定如何继续,因为$ ref东西可能会抛出东西。


我在想解决方案将以某种方式通过不使用以下方式强制将所有Foos呈现在FooList中:


PreserveReferencesHandling = PreserveReferencesHandling.Objects

但这似乎很浪费。


慕侠2389804
浏览 1178回答 3
3回答

米琪卡哇伊

您从服务器接收的json对象包含循环引用。在使用该对象之前,您必须首先$ref从该对象中删除所有属性,这意味着$ref : "1"必须放置该链接指向的对象来代替该对象。您的情况可能是指向ID为1的用户对象为此,您应该在github上查看Douglas Crockfords插件。有一个cycle.js可以为您完成工作。或者您可以使用以下代码(未经测试):function resolveReferences(json) {&nbsp; &nbsp; if (typeof json === 'string')&nbsp; &nbsp; &nbsp; &nbsp; json = JSON.parse(json);&nbsp; &nbsp; var byid = {}, // all objects by id&nbsp; &nbsp; &nbsp; &nbsp; refs = []; // references to objects that could not be resolved&nbsp; &nbsp; json = (function recurse(obj, prop, parent) {&nbsp; &nbsp; &nbsp; &nbsp; if (typeof obj !== 'object' || !obj) // a primitive value&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return obj;&nbsp; &nbsp; &nbsp; &nbsp; if ("$ref" in obj) { // a reference&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var ref = obj.$ref;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (ref in byid)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return byid[ref];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // else we have to make it lazy:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; refs.push([parent, prop, ref]);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; &nbsp; &nbsp; } else if ("$id" in obj) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var id = obj.$id;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; delete obj.$id;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ("$values" in obj) // an array&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; obj = obj.$values.map(recurse);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else // a plain object&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (var prop in obj)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; obj[prop] = recurse(obj[prop], prop, obj)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; byid[id] = obj;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return obj;&nbsp; &nbsp; })(json); // run it!&nbsp; &nbsp; for (var i=0; i<refs.length; i++) { // resolve previously unknown references&nbsp; &nbsp; &nbsp; &nbsp; var ref = refs[i];&nbsp; &nbsp; &nbsp; &nbsp; ref[0][ref[1]] = byid[refs[2]];&nbsp; &nbsp; &nbsp; &nbsp; // Notice that this throws if you put in a reference at top-level&nbsp; &nbsp; }&nbsp; &nbsp; return json;}&nbsp;&nbsp;让我知道是否有帮助!

小怪兽爱吃肉

如果您利用JSON.parse的reviver参数,这实际上非常简单。下面的例子。请参阅浏览器控制台以获取输出,因为StackOverflow的代码段控制台输出将无法提供有关结果的准确图片。// example JSONvar j = '{"$id":"0","name":"Parent","child":{"$id":"1", "name":"Child","parent":{"$ref":"0"}},"nullValue":null}'function parseAndResolve(json) {&nbsp; &nbsp; var refMap = {};&nbsp; &nbsp; return JSON.parse(json, function (key, value) {&nbsp; &nbsp; &nbsp; &nbsp; if (key === '$id') {&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; refMap[value] = this;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // return undefined so that the property is deleted&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return void(0);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if (value && value.$ref) { return refMap[value.$ref]; }&nbsp; &nbsp; &nbsp; &nbsp; return value;&nbsp;&nbsp; &nbsp; });}console.log(parseAndResolve(j));
打开App,查看更多内容
随时随地看视频慕课网APP