将平面JSON数组转换为嵌套JSON的通用方法 [英] Generic method to convert a flat JSON array to nested JSON

查看:198
本文介绍了将平面JSON数组转换为嵌套JSON的通用方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个如下的JSON对象

I have a JSON object as below

[
  {
    "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
  }
]

IdParentId字段显示项目之间的关系.我需要使用C#将其作为嵌套的JSON. 由于会有许多这样的模型,所以我不想为每个模型创建单独的类. C#中是否有通用方法将采用平面JSON数组,将IDParentId字段作为输入,然后将数组中所有其他字段也返回给我一个嵌套的JSON?例如,我正在寻找嵌套JSON的输出,如下所示:

The Id and ParentId fields show the relation between the items. I need to make it as a nested JSON using C#. Since there will be many such models, I don't want to create individual classes for each model. Is there a generic approach in C# that will take a flat JSON array, take the ID and ParentId fields as input and then return me a nested JSON with all other fields in the array as well? For example, I am looking for an output of nested JSON as below:

[
  {
    "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
          }
        ]
      }
    ]
  }
]

推荐答案

如果使用 Json.Net ,您可以使用 LINQ-to-JSON以通用方式进行此转换API (JObjects).这个想法是解析JSON数组,并将所有单个项添加到以Id键控的字典中.然后,遍历字典项,并为每个项尝试查找父项.如果找到了父项,则将该项目添加到父项的items数组中(如果需要,则创建它).否则,将该项目添加到root数组.在此过程中,请从每个项目中删除depth属性,因为您似乎不需要在输出中使用它.最后,只需将root数组转储为字符串即可得到最终结果.

If you use Json.Net, you can do this conversion in a generic way using the LINQ-to-JSON API (JObjects). The idea is to parse the JSON array and add all the individual items to a dictionary keyed by Id. Then, loop over the dictionary items, and for each one, try to look up the parent. If the parent is found, add the item to the parent's items array (creating it if needed). Otherwise, add the item to the root array. Along the way, remove the depth property from each item, since you don't seem to want that in the output. Lastly, just dump the root array to string to get the final result.

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());

提琴: https://dotnetfiddle.net/Buza6T

这篇关于将平面JSON数组转换为嵌套JSON的通用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆