首页 > 解决方案 > 将带有数组的 json 结构展平为多个没有数组的平面对象

问题描述

我不确定我是否 100% 正确地描述了主题中的问题,但我相信这些示例可以解决问题。

我有如下 JSON 结构(注意:这可能会改变的可能性很小,所以我需要倾向于通用解决方案)

一张包含多个行项目的发票

{
    "contactName": "Company",
    "lineItems": [
     {
        "quantity": 7.0,
        "description": "Beer No* 45.5 DIN KEG"
     },
     {
        "quantity": 2.0,
        "description": "Beer Old 49.5 DIN KEG"
     }
     ],
    "invoiceNumber": "C6188372"
}

这是想要的结果数据结构(具有重复数据和不同行项目信息的多张发票):

[{
    "contactName": "Company",
    "quantity": 7.0,
    "description": "Beer No* 45.5 DIN KEG"
    "invoiceNumber": "C6188372"
},{
    "contactName": "Company",
    "quantity": 2.0,
    "description": "Beer Old 49.5 DIN KEG"
    "invoiceNumber": "C6188372"
}]

因此,“发票”中的每个“行项目”都应该“产生”具有重复其他元素的新发票。

可以接受围绕结果数据结构的微小变化,我可以围绕它调整我的代码。我一直在使用几个类似的问题,例如:

有关更多背景信息,我需要将其用于 CSV 导出。所以结果集应该是生成的 CSV 中的两行。

非常感谢任何提示/提示。谢谢。

标签: c#jsonrecursionjson.net

解决方案


你可以用这样的函数来做到这一点:

//Pass in the name of the array property you want to flatten
public string FlattenJson(string input, string arrayProperty)
{
    //Convert it to a JObject
    var unflattened = JsonConvert.DeserializeObject<JObject>(input);

    //Return a new array of items made up of the inner properties
    //of the array and the outer properties
    var flattened = ((JArray)unflattened[arrayProperty])
        .Select(item => new JObject(
            unflattened.Properties().Where(p => p.Name != arrayProperty), 
            ((JObject)item).Properties()));

    //Convert it back to Json
    return JsonConvert.SerializeObject(flattened);
}

并这样称呼它:

var flattenedJson = FlattenJson(inputJson, "lineItems");

推荐阅读