Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将平面JSON转换为嵌套JSON_C#_Json_Algorithm - Fatal编程技术网

C# 将平面JSON转换为嵌套JSON

C# 将平面JSON转换为嵌套JSON,c#,json,algorithm,C#,Json,Algorithm,我有一个类似下面的平面JSON(我不知道该怎么称呼它,我希望平面是正确的词) 请注意,这些字段不是按顺序排序的 我想将其转换为嵌套的JSON,如下所示: { "id":12947, "name":{ "first_name":"Honey", "last_name":"Moon" }, "address":{ "street":{ "number":"23", "nam

我有一个类似下面的平面JSON(我不知道该怎么称呼它,我希望平面是正确的词)

请注意,这些字段不是按顺序排序的

我想将其转换为嵌套的JSON,如下所示:

{
    "id":12947,
    "name":{
        "first_name":"Honey",
        "last_name":"Moon"
    },
    "address":{
        "street":{
            "number":"23",
            "name":"Narrow Street"
        },    
        "city":{
            "code":"LL",
            "name":"Lalaland"
        }
    },
    "books": [
        {
            "title":"The long story",
            "author": {
                "first_name":"Brew",
                "last_name":"Beating"
            },
            "type":"novel"
        },        
        {
            "title":"Money and morality",
            "author":{
                "first_name":"Chris",
                "last_name":"Mas"
            },
            "type":"self-help"
        }
    ]
}
转换它的好算法是什么

我是一个C#人,我打算使用Newtonsoft.Json将输入Json解析为一个JObject,然后遍历所有字段以检查它们的键并创建嵌套的JObject。对于数组,我对每个数组项重复相同的过程


你有更好的主意吗?

这是我为感兴趣的人提供的解决方案

public static string ConvertFlatJson(string input)
{
    var token = JToken.Parse(input);

    if (token is JObject obj)
    {
        return ConvertJObject(obj).ToString();
    }

    if (token is JArray array)
    {
        return ConvertArray(array).ToString();
    }

    return input;
}

private static JObject ConvertJObject(JObject input)
{
    var enumerable = ((IEnumerable<KeyValuePair<string, JToken>>)input).OrderBy(kvp => kvp.Key);

    var result = new JObject();
    foreach (var outerField in enumerable)
    {
        var key = outerField.Key;
        var value = outerField.Value;

        if (value is JArray array)
        {
            value = ConvertArray(array);
        }

        var fieldNames = key.Split('.');
        var currentObj = result;

        for (var fieldNameIndex = 0; fieldNameIndex < fieldNames.Length; fieldNameIndex++)
        {
            var fieldName = fieldNames[fieldNameIndex];

            if (fieldNameIndex == fieldNames.Length - 1)
            {
                currentObj[fieldName] = value;
                continue;
            }

            if (currentObj.ContainsKey(fieldName))
            {
                currentObj = (JObject)currentObj[fieldName];
                continue;
            }

            var newObj = new JObject();
            currentObj[fieldName] = newObj;
            currentObj = newObj;
        }
    }

    return result;
}

private static JArray ConvertArray(JArray array)
{
    var resultArray = new JArray();

    foreach (var arrayItem in array)
    {
        if (!(arrayItem is JObject))
        {
            resultArray.Add(arrayItem);
            continue;
        }

        var itemObj = (JObject)arrayItem;

        resultArray.Add(ConvertJObject(itemObj));
    }

    return resultArray;
}
publicstaticstringconvertflatjson(字符串输入)
{
var token=JToken.Parse(输入);
if(标记为JObject obj)
{
返回ConvertJObject(obj.ToString();
}
if(标记为JArray数组)
{
返回ConvertArray(array.ToString();
}
返回输入;
}
私有静态JObject ConvertJObject(JObject输入)
{
var enumerable=((IEnumerable)input).OrderBy(kvp=>kvp.Key);
var result=new JObject();
foreach(可枚举中的var outerField)
{
var key=outerField.key;
var值=外部字段值;
if(值为JArray数组)
{
值=转换数组(数组);
}
var fieldNames=key.Split('.');
var currentObj=结果;
对于(var fieldNameIndex=0;fieldNameIndex
不,我没有任何想法,您已经描述了正确的方法。
public static string ConvertFlatJson(string input)
{
    var token = JToken.Parse(input);

    if (token is JObject obj)
    {
        return ConvertJObject(obj).ToString();
    }

    if (token is JArray array)
    {
        return ConvertArray(array).ToString();
    }

    return input;
}

private static JObject ConvertJObject(JObject input)
{
    var enumerable = ((IEnumerable<KeyValuePair<string, JToken>>)input).OrderBy(kvp => kvp.Key);

    var result = new JObject();
    foreach (var outerField in enumerable)
    {
        var key = outerField.Key;
        var value = outerField.Value;

        if (value is JArray array)
        {
            value = ConvertArray(array);
        }

        var fieldNames = key.Split('.');
        var currentObj = result;

        for (var fieldNameIndex = 0; fieldNameIndex < fieldNames.Length; fieldNameIndex++)
        {
            var fieldName = fieldNames[fieldNameIndex];

            if (fieldNameIndex == fieldNames.Length - 1)
            {
                currentObj[fieldName] = value;
                continue;
            }

            if (currentObj.ContainsKey(fieldName))
            {
                currentObj = (JObject)currentObj[fieldName];
                continue;
            }

            var newObj = new JObject();
            currentObj[fieldName] = newObj;
            currentObj = newObj;
        }
    }

    return result;
}

private static JArray ConvertArray(JArray array)
{
    var resultArray = new JArray();

    foreach (var arrayItem in array)
    {
        if (!(arrayItem is JObject))
        {
            resultArray.Add(arrayItem);
            continue;
        }

        var itemObj = (JObject)arrayItem;

        resultArray.Add(ConvertJObject(itemObj));
    }

    return resultArray;
}