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

如何使用JSONata获取两个对象的差异内容?

在JSONata中获取两个对象的差异内容

JSONata本身没有内置的对象差异提取函数,但可以通过自定义表达式或递归函数来实现需求,以下是两种实用方案:

1. 顶层属性差异提取

如果只需要对比对象的顶层属性,可使用以下表达式(假设待对比的两个对象为$left和$right):

$reduce(
  $keys($merge([$left, $right])),
  function($acc, $key) {
    $let(
      [
        $lVal := $left[$key],
        $rVal := $right[$key]
      ],
      $if(
        $lVal != $rVal,
        $merge([
          $acc,
          {
            $key: {
              "left": $lVal,
              "right": $rVal
            }
          }
        ]),
        $acc
      )
    )
  },
  {}
)

逻辑说明:

  • $merge([$left, $right])合并两个对象的所有键,确保不会遗漏任何一方的属性
  • $reduce遍历所有键,逐个对比左右对象的属性值
  • 若值不相等,则将该属性的左右值存入结果对象,最终返回只包含差异属性的对象

2. 递归处理嵌套对象差异

如果对象包含多层嵌套结构,需要递归遍历所有层级的属性,可定义一个递归函数:

$function diff($a, $b) {
  $let(
    $allKeys := $keys($merge([$a, $b])),
    $reduce(
      $allKeys,
      function($acc, $key) {
        $let(
          [
            $aVal := $a[$key],
            $bVal := $b[$key]
          ],
          $if(
            $type($aVal) = "object" and $type($bVal) = "object",
            $let(
              $nestedDiff := diff($aVal, $bVal),
              $if($nestedDiff != {}, $merge([$acc, {$key: $nestedDiff}]), $acc)
            ),
            $if(
              $aVal != $bVal,
              $merge([$acc, {$key: {"left": $aVal, "right": $bVal}}]),
              $acc
            )
          )
        )
      },
      {}
    )
  )
}

使用方式:

直接调用函数传入两个对象即可,例如diff(obj1, obj2),返回结果会递归展开所有嵌套层级的差异,仅保留值不同的属性路径。

额外注意事项

  • 数组处理:上述方案会将数组作为整体对比,如果需要数组元素级的差异,需额外添加数组遍历对比的逻辑(比如判断$type为array时,遍历元素逐个对比)
  • 特殊值判断:如果需要区分“属性不存在”和“属性值为null”,可调整判断逻辑,比如用$exists($left[$key])来检测属性是否存在

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 07:15:36