You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何移除JSON Array父级并保留子JSON数组

嘿,我懂你遇上的麻烦了——从SQL Server存储过程拿到的JSON嵌套了一堆没必要的数组层级,搜了半天没找到对应的移除方案对吧?刚好我之前处理过几乎一模一样的场景,给你几个实用的解决办法:

方案1:从SQL Server源头修正(最推荐)

既然JSON是存储过程生成的,最好直接在生成阶段就避免多余的数组。SQL Server的FOR JSON语句如果用了默认的PATH或AUTO模式,很容易给单条结果套上数组壳子。你可以调整存储过程里的JSON生成逻辑:

比如原来的生成代码可能是这样的:

SELECT 
  (SELECT 'kode' AS name, 
          (SELECT value, RankNum FROM YourDiagnosisTable FOR JSON PATH) AS value
   FOR JSON PATH) AS KODE,
  -- HEALING字段同理生成
FOR JSON PATH

改成给嵌套的FOR JSON加上WITHOUT_ARRAY_WRAPPER参数,直接去掉多余的数组包裹:

SELECT 
  (SELECT 'kode' AS name, 
          (SELECT value, RankNum FROM YourDiagnosisTable FOR JSON PATH) AS value
   FOR JSON PATH, WITHOUT_ARRAY_WRAPPER) AS KODE,
  -- HEALING字段同样加上WITHOUT_ARRAY_WRAPPER
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER

这样生成的JSON就会是干净的对象结构,不会有多余的[]包裹。

方案2:应用层代码处理(适合无法修改存储过程的情况)

如果没法动存储过程,就在拿到JSON后用代码扁平化嵌套数组。这里给你两种常用语言的实现:

JavaScript版本

写个递归函数自动处理所有长度为1的数组:

function flattenNestedArrays(obj) {
  // 如果是数组且只有一个元素,直接取元素递归处理
  if (Array.isArray(obj)) {
    return obj.length === 1 ? flattenNestedArrays(obj[0]) : obj.map(item => flattenNestedArrays(item));
  }
  // 如果是对象,遍历所有属性递归处理
  else if (typeof obj === 'object' && obj !== null) {
    const result = {};
    for (const key in obj) {
      result[key] = flattenNestedArrays(obj[key]);
    }
    return result;
  }
  // 基本类型直接返回
  return obj;
}

// 用法示例
const rawJson = [{"KODE":[{"name":"kode","value":[{"value":"DIAG001","RankNum":1},{"value":"DIAG002","RankNum":1}]}],"HEALING":[{"name":"Encountrance","value":[...]}]}];
const cleanedJson = flattenNestedArrays(rawJson);
console.log(cleanedJson);

C#版本(用Newtonsoft.Json)

using Newtonsoft.Json.Linq;

public static JToken FlattenJson(JToken token)
{
    if (token.Type == JTokenType.Array)
    {
        var array = (JArray)token;
        // 数组长度为1则取第一个元素继续处理
        if (array.Count == 1)
        {
            return FlattenJson(array[0]);
        }
        // 数组长度大于1则逐个处理元素
        return new JArray(array.Select(FlattenJson));
    }
    else if (token.Type == JTokenType.Object)
    {
        var obj = (JObject)token;
        var result = new JObject();
        foreach (var prop in obj.Properties())
        {
            result[prop.Name] = FlattenJson(prop.Value);
        }
        return result;
    }
    return token;
}

// 调用示例
var rawJson = "[{\"KODE\":[{\"name\":\"kode\",\"value\":[{\"value\":\"DIAG001\",\"RankNum\":1},...]}],\"HEALING\":[...]}]";
var cleanedToken = FlattenJson(JToken.Parse(rawJson));
var finalJson = cleanedToken.ToString();
方案3:SQL Server事后修正(临时应急用)

如果必须在数据库里处理已生成的JSON,可以用JSON_QUERY和JSON_MODIFY手动移除数组层级:

DECLARE @rawJson NVARCHAR(MAX) = '[{"KODE":[{"name":"kode","value":[{"value":"DIAG001","RankNum":1},...]}],"HEALING":[...]}]';

-- 移除最外层数组
SET @rawJson = JSON_QUERY(@rawJson, '$[0]');

-- 移除KODE字段的数组包裹
SET @rawJson = JSON_MODIFY(@rawJson, '$.KODE', JSON_QUERY(@rawJson, '$.KODE[0]'));

-- 移除HEALING字段的数组包裹
SET @rawJson = JSON_MODIFY(@rawJson, '$.HEALING', JSON_QUERY(@rawJson, '$.HEALING[0]'));

-- 如果还有内层的value数组需要处理,继续用同样逻辑
SET @rawJson = JSON_MODIFY(@rawJson, '$.KODE.value', JSON_QUERY(@rawJson, '$.KODE.value'));

SELECT @rawJson AS CleanedJson;

这个方法适合临时修正,但效率不如从源头生成干净JSON,不建议长期用。

内容的提问来源于stack exchange,提问作者flix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:06:58