我有一个JSON对象,如下所示
[
{
"Id": 7,
"Name": "Colocation Folder",
"ParentId": 1,
"depth": 0
},
{
"Id": 8,
"Name": "CoLo Real Estate",
"ParentId": 7,
"depth": 1
},
{
"Id": 10,
"Name": "CoLo: Burst",
"ParentId": 7,
"depth": 1
},
{
"Id": 34,
"Name": "CoLo Dedicated Bandwidth",
"ParentId": 7,
"depth": 1
},
{
"Id": 10035,
"Name": "Infrastructure as a Service",
"ParentId": 7,
"depth": 1
},
{
"Id": 10037,
"Name": "Software as a Service",
"ParentId": 7,
"depth": 1
},
{
"Id": 10038,
"Name": "IaaS Component Upgrade",
"ParentId": 7,
"depth": 1
},
{
"Id": 668,
"Name": "CoLo Misc Folder",
"ParentId": 7,
"depth": 1
},
{
"Id": 758,
"Name": "CoLo: Conduit Fee",
"ParentId": 668,
"depth": 2
},
{
"Id": 765,
"Name": "CoLo: Private VLAN",
"ParentId": 668,
"depth": 2
}
]
Id
和ParentId
字段显示项目之间的关系。我需要使用C#将其作为嵌套的JSON。
由于会有很多这样的模型,我不想为每个模型创建单独的类。在C#中是否存在采用平面JSON数组的通用方法,将ID
和ParentId
字段作为输入,然后返回一个嵌套的JSON以及数组中的所有其他字段?例如,我正在寻找嵌套JSON的输出,如下所示:
[
{
"Id": 7,
"Name": "Colocation Folder",
"items": [
{
"Id": 8,
"Name": "CoLo Real Estate",
"ParentId": 7
},
{
"Id": 10,
"Name": "CoLo: Burst",
"ParentId": 7
},
{
"Id": 34,
"Name": "CoLo Dedicated Bandwidth",
"ParentId": 7
},
{
"Id": 10035,
"Name": "Infrastructure as a Service",
"ParentId": 7
},
{
"Id": 10037,
"Name": "Software as a Service",
"ParentId": 7
},
{
"Id": 10038,
"Name": "IaaS Component Upgrade",
"ParentId": 7
},
{
"Id": 668,
"Name": "CoLo Misc Folder",
"ParentId": 7,
"items": [
{
"Id": 758,
"Name": "CoLo: Conduit Fee",
"ParentId": 668
},
{
"Id": 765,
"Name": "CoLo: Private VLAN",
"ParentId": 668
}
]
}
]
}
]
答案 0 :(得分:0)
如果您使用Json.Net,则可以使用LINQ-to-JSON API(JObjects)以通用方式执行此转换。我们的想法是解析JSON数组并将所有单独的项添加到由Id
键入的字典中。然后,循环遍历字典项,并为每个项目尝试查找父项。如果找到父项,请将项添加到父项items
数组中(如果需要,可以创建它)。否则,将项添加到root
数组。在此过程中,从每个项目中删除depth
属性,因为您似乎不希望在输出中使用该属性。最后,只需将root
数组转储到字符串即可获得最终结果。
var dict = JArray.Parse(json)
.Children<JObject>()
.ToDictionary(jo => (string)jo["Id"], jo => new JObject(jo));
var root = new JArray();
foreach (JObject obj in dict.Values)
{
JObject parent;
string parentId = (string)obj["ParentId"];
if (parentId != null && dict.TryGetValue(parentId, out parent))
{
JArray items = (JArray)parent["items"];
if (items == null)
{
items = new JArray();
parent.Add("items", items);
}
items.Add(obj);
}
else
{
root.Add(obj);
}
JProperty depth = obj.Property("depth");
if (depth != null) depth.Remove();
}
Console.WriteLine(root.ToString());
答案 1 :(得分:0)
您可以使用JSON.Net这样的动态对象来动态检测您的属性,然后您可以使用所需的嵌套构建一个新的json对象: 使用Newtonsoft.Json; 使用Newtonsoft.Json.Linq;
dynamic d = JArray.Parse(stringy);
foreach(var ob in d)
{
if(ob.ParentID != ob.Id)
{
string debug = "oh snapple, it's a child object";
}
}
答案 2 :(得分:0)
在jsFiddle full source code上为您分享我的工作代码
递归函数是:
function getNestedChildren(arr, parent) {
var out = []
for(var i in arr) {
if(arr[i].parent == parent) {
var children = getNestedChildren(arr, arr[i].id)
if(children.length) {
arr[i].children = children
}
out.push(arr[i])
}
}
return out
}
完整的源代码:
function getNestedChildren(arr, parent) {
var out = []
for(var i in arr) {
if(arr[i].ParentId == parent) {
var items = getNestedChildren(arr, arr[i].Id)
if(items.length) {
arr[i].items = items
}
out.push(arr[i])
}
}
return out
}
var flat_array = [
{
"Id": 7,
"Name": "Colocation Folder",
"ParentId": 1,
"depth": 0
},
{
"Id": 8,
"Name": "CoLo Real Estate",
"ParentId": 7,
"depth": 1
},
{
"Id": 10,
"Name": "CoLo: Burst",
"ParentId": 7,
"depth": 1
},
{
"Id": 34,
"Name": "CoLo Dedicated Bandwidth",
"ParentId": 7,
"depth": 1
},
{
"Id": 10035,
"Name": "Infrastructure as a Service",
"ParentId": 7,
"depth": 1
},
{
"Id": 10037,
"Name": "Software as a Service",
"ParentId": 7,
"depth": 1
},
{
"Id": 10038,
"Name": "IaaS Component Upgrade",
"ParentId": 7,
"depth": 1
},
{
"Id": 668,
"Name": "CoLo Misc Folder",
"ParentId": 7,
"depth": 1
},
{
"Id": 758,
"Name": "CoLo: Conduit Fee",
"ParentId": 668,
"depth": 2
},
{
"Id": 765,
"Name": "CoLo: Private VLAN",
"ParentId": 668,
"depth": 2
}
]
var nested = getNestedChildren(flat_array, 1)
console.log(nested)