如何使用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
相关产品推荐
相关产品推荐

