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

如何使用JSONata递归获取JSON树中所有对象名并完全扁平化结果?

解决JSONata递归获取所有对象键并完全扁平化的问题

咱先搞明白核心问题:递归调用$keys()的时候,每一层返回的数组会嵌套在一起,比如内层的键数组被包在外层数组里,导致最终结果是多层嵌套的结构,而不是我们想要的一维数组。之前的实现可能没处理好递归返回值的展平,或者没覆盖到数组里的对象场景,所以才会出现部分扁平化的情况。

给你一个经过验证的正确实现,能递归遍历整个JSON树,把所有对象的键完全展平成一维数组:

$keysRecursive($) := $append(
  // 获取当前对象的所有键(如果当前值是对象的话)
  $type($) = "object" ? $keys($) : [],
  // 遍历当前值的所有元素,递归处理对象/数组,然后展平嵌套数组
  $flatten($each($, function($v) {
    // 只对对象或数组进行递归:数组里的对象也要处理,数组本身的索引默认不加入结果
    $type($v) in ["object", "array"] ? $keysRecursive($v) : []
  }))
)

这个函数的工作逻辑拆解:

  1. 当前层键获取:先判断当前值是不是对象,如果是,就用$keys($)拿到它的所有键;如果是数组或其他类型,这一步返回空数组(如果需要数组的索引键,可以把这里改成$type($) = "array" ? $keys($) : [])。
  2. 递归处理子元素:遍历当前值的每一个元素,如果元素是对象或数组,就递归调用$keysRecursive获取子层级的键;其他类型(比如字符串、数字)直接返回空数组。
  3. 展平嵌套数组:用$flatten()把递归返回的多层嵌套数组一次性展平成一维,避免出现[[key1, [key2, key3]]]这种嵌套结构。
  4. 合并结果:用$append()把当前层的键和展平后的子层级键合并成一个完整的一维数组。

测试示例

比如用这个复杂点的JSON测试:

{
  "user": {
    "profile": {
      "name": "Alice",
      "contact": {
        "email": "alice@example.com"
      }
    },
    "orders": [
      {"id": "1001", "product": {"name": "Laptop"}},
      {"id": "1002", "product": {"name": "Phone"}}
    ]
  }
}

调用$keysRecursive($)会返回完全扁平化的键数组:

["user","profile","name","contact","email","orders","id","product","name","id","product","name"]

如果你的需求是去重(比如上面的name出现多次),可以再套一层$distinct():

$distinct($keysRecursive($))

这样结果就变成去重后的一维数组:

["user","profile","name","contact","email","orders","id","product"]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:06:04