如何在C#中将JSON数组对象的重复公共字段移至外层
在C#中提取JSON数组公共字段到外层的实现方法
需求说明
原输入JSON结构:
{ "data": [ { "country": "China", "color" : "Red", "pet" : "Cat", "name" : "Mark", "height_unit_name" : "cm" }, { "country": "China", "color" : "black", "pet" : "dog", "name" : "Jane", "height_unit_name" : "cm" } ] }
需要将数组内所有对象共有的country和height_unit_name字段移到外层,同时移除数组元素中的这些字段,得到目标结构:
{ "country": "China", "height_unit_name": "cm", "data": [ { "color": "Red", "pet": "Cat", "name": "Mark" }, { "color": "black", "pet": "dog", "name": "Jane" } ] }
实现方案
方法一:使用Newtonsoft.Json(Json.NET)
这是C#生态中广泛使用的JSON处理库,需要先通过NuGet安装Newtonsoft.Json包。
using Newtonsoft.Json; using Newtonsoft.Json.Linq; class Program { static void Main() { // 原JSON字符串 string originalJson = @" { ""data"": [ { ""country"": ""China"", ""color"" : ""Red"", ""pet"" : ""Cat"", ""name"" : ""Mark"", ""height_unit_name"" : ""cm"" }, { ""country"": ""China"", ""color"" : ""black"", ""pet"" : ""dog"", ""name"" : ""Jane"", ""height_unit_name"" : ""cm"" } ] }"; // 解析原JSON为JObject JObject originalObj = JObject.Parse(originalJson); JArray dataArray = (JArray)originalObj["data"]; // 处理空数组的边界情况 if (dataArray.Count == 0) { Console.WriteLine(originalObj.ToString(Formatting.Indented)); return; } // 从第一个元素提取公共字段(题目保证所有元素值相同) JToken firstItem = dataArray[0]; string country = firstItem["country"].ToString(); string heightUnit = firstItem["height_unit_name"].ToString(); // 将公共字段添加到外层对象 originalObj.Add("country", country); originalObj.Add("height_unit_name", heightUnit); // 遍历数组,移除每个元素的公共字段 foreach (JObject item in dataArray) { item.Remove("country"); item.Remove("height_unit_name"); } // 输出格式化后的目标JSON string targetJson = originalObj.ToString(Formatting.Indented); Console.WriteLine(targetJson); } }
方法二:使用System.Text.Json(.NET Core 3.0+自带)
如果使用.NET Core 3.0及以上版本,可以直接用官方自带的System.Text.Json,无需额外安装包。
using System.Text.Json; using System.Text.Json.Nodes; class Program { static void Main() { string originalJson = @" { ""data"": [ { ""country"": ""China"", ""color"" : ""Red"", ""pet"" : ""Cat"", ""name"" : ""Mark"", ""height_unit_name"" : ""cm"" }, { ""country"": ""China"", ""color"" : ""black"", ""pet"" : ""dog"", ""name"" : ""Jane"", ""height_unit_name"" : ""cm"" } ] }"; // 解析原JSON为JsonObject JsonObject originalObj = JsonNode.Parse(originalJson).AsObject(); JsonArray dataArray = originalObj["data"].AsArray(); // 处理空数组的边界情况 if (dataArray.Count == 0) { Console.WriteLine(JsonSerializer.Serialize(originalObj, new JsonSerializerOptions { WriteIndented = true })); return; } // 提取公共字段 JsonObject firstItem = dataArray[0].AsObject(); string country = firstItem["country"].GetValue<string>(); string heightUnit = firstItem["height_unit_name"].GetValue<string>(); // 添加公共字段到外层 originalObj.Add("country", country); originalObj.Add("height_unit_name", heightUnit); // 移除数组元素中的公共字段 foreach (JsonObject item in dataArray) { item.Remove("country"); item.Remove("height_unit_name"); } // 输出目标JSON string targetJson = JsonSerializer.Serialize(originalObj, new JsonSerializerOptions { WriteIndented = true }); Console.WriteLine(targetJson); } }
关键说明
- 由于题目明确数组内所有对象的
country和height_unit_name值完全相同,因此直接取第一个元素的值即可,无需校验所有元素 - 两种方法均采用动态JSON操作,无需预先定义实体类,适合灵活调整JSON结构
- Newtonsoft.Json兼容性更好,支持.NET Framework等旧版本;System.Text.Json是官方原生库,性能更优且无需额外依赖
内容的提问来源于stack exchange,提问作者MhooP
相关产品推荐
相关产品推荐

