C# 将平面JSON转换为嵌套JSON
我有一个类似下面的平面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
{
"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;
}