Jsonata 查找包含文本的字段并将其替换为其他文本

Jsonata 查找包含文本的字段并将其替换为其他文本,jsonata,Jsonata,在下面的JSON示例中,如何找到包含字符串“Choice”的所有元素,并将它们替换为另一个字符串,例如“Grade”。 因此,以下所有字段名称“***选项”应改为“***等级” 我已将预期输出粘贴到下面。考虑到我不知道有多少字段会有字符串“Choice”,我不想简单地执行[$in~>|**[firstChoice]{“firstGrade”:firstChoice},[“firstChoice”]|],这是一个直接的查找和替换 { "data": { "resourceType":

在下面的JSON示例中,如何找到包含字符串“Choice”的所有元素,并将它们替换为另一个字符串,例如“Grade”。 因此,以下所有字段名称“***选项”应改为“***等级”

我已将预期输出粘贴到下面。考虑到我不知道有多少字段会有字符串“Choice”,我不想简单地执行
[$in~>|**[firstChoice]{“firstGrade”:firstChoice},[“firstChoice”]|]
,这是一个直接的查找和替换

{
  "data": {
    "resourceType": "Bundle",
    "id": "e919c820-71b9-4e4b-a1c8-c2fef62ea911",
    "firstChoice": "xxx",
    "type": "collection",
    "entry": [
      {
        "resource": {
          "resourceType": "Condition",
          "id": "SMART-Condition-342",
          "code": {
            "coding": [
              {
                "system": "http://snomed.info/sct",
                "code": "38341003",
                "display": "Essential hypertension",
                "firstChoice": "xxx"
              }
            ],
            "text": "Essential hypertension"
          },
          "clinicalStatus": "active",
          "secondChoice": "xxx"
        },
        "search": {
          "mode": "match"
        }
      }
    ]
  }
}
预期产量

{
  "data": {
    "resourceType": "Bundle",
    "id": "e919c820-71b9-4e4b-a1c8-c2fef62ea911",
    "firstGrade": "xxx",
    "type": "collection",
    "entry": [
      {
        "resource": {
          "resourceType": "Condition",
          "id": "SMART-Condition-342",
          "code": {
            "coding": [
              {
                "system": "http://snomed.info/sct",
                "code": "38341003",
                "display": "Essential hypertension",
                "firstGrade": "xxx"
              }
            ],
            "text": "Essential hypertension"
          },
          "clinicalStatus": "active",
          "secondGrade": "xxx"
        },
        "search": {
          "mode": "match"
        }
      }
    ]
  }
}

可能有更简单的方法,但这是我在JSONata中提出的一个表达式:

(
  $prefixes := $keys(**)[$ ~> /Choice$/].$substringBefore('Choice');
  $reduce($prefixes, function($acc, $prefix) {(
    $choice := $prefix & "Choice";
    $acc ~> | ** [$lookup($choice)] | {$prefix & "Grade": $lookup($choice)}, [$choice] |
  )}, $$)
)
看起来很糟糕,但我还是会解释我是怎么建立起来的

你从表达式开始

$~>|**[firstChoice]{“firstGrade”:firstChoice},[“firstChoice”]|

如果您只想替换一个选项,并且您知道其全名,那么这很好。如果要替换多个,则可以按如下方式将它们链接在一起:

$ ~> | ** [firstChoice] | {"firstGrade": firstChoice}, ["firstChoice"] |
  ~> | ** [secondChoice] | {"secondGrade": secondChoice}, ["secondChoice"] |
  ~> | ** [thirdChoice] | {"thirdGrade": thirdChoice}, ["thirdChoice"] |
此时,您可以创建一个高阶函数,该函数使用choice前缀并返回部分替换(请注意,
|…|…|
语法生成一个函数)。然后,您可以使用内置的
$reduce()
高阶函数将它们链接在一起,形成一个前缀数组。你会得到这样的结果:

(
  $prefixes := ["first", "second", "third"];
  $reduce($prefixes, function($acc, $prefix) {(
    $choice := $prefix & "Choice";
    $acc ~> | ** [$lookup($choice)] | {$prefix & "Grade": $lookup($choice)}, [$choice] |
  )}, $$)
)
但是,如果您事先不知道前缀集,并且希望选择(例如)以“Choice”结尾的所有属性名称,则以下表达式将为您提供:

$prefixes:=$keys(**)[$~>/Choice$/].$substringBefore('Choice'))


这就是我最后的表情。你可以在你的数据上进行实验。

这太棒了。我没有想到要用$lookup来做这个。谢谢你的回答。这与我试图做但无法做到的事情是一致的。我想的另一种方法是循环所有元素,只需在字段名上执行$replace,但基于我有限的jsonata知识,我意识到这可能不适用于克隆/转换等。但是你的回答解决了我的问题