使用 Jolt 将数组转置到另一个数组

Transpose an array to another one with Jolt

我努力将输入的 json 字符串转换为另一个带有 Jolt 的字符串,如下所示。但是我无法编写正确的 Jolt Spec 来实现转换,Jolt 可以做这样的事情吗?谢谢!

输入:

{
  "result": [
    {
      "name": "AAA",
      "value1": "AAA-111",
      "value2": "AAA-222",
      "value3": "AAA-333"
    },
    {
      "name": "BBB",
      "value1": "BBB-111",
      "value2": "BBB-222",
      "value3": "BBB-333"
    },
    {
      "name": "CCC",
      "value1": "CCC-111",
      "value2": "CCC-222",
      "value3": "CCC-333"
    }
  ]
}

输出:

{
  "result": [
    {
      "value_name":"value1",
      "AAA":"AAA-111",
      "BBB":"BBB-111",
      "CCC":"CCC-111"
    },
    {
      "value_name":"value2",
      "AAA":"AAA-222",
      "BBB":"BBB-222",
      "CCC":"CCC-222"
    },
    {
      "value_name":"value3",
      "AAA":"AAA-333",
      "BBB":"BBB-333",
      "CCC":"CCC-333"
    }
  ]
}

这不仅仅是 "Transpose an array to another one"。

这里实际上发生了 4 件事:

  1. Pivot/group传入的数据变成"value1","value2","value3"
  2. 从假定为连字符分隔的密钥中提取新密钥 "AAA"。又名构建 "AAA" : "AAA-111".
  3. 获取 "value1"、"value2" 等作为 "value_name" 的值而不是 json.
  4. 中的键
  5. 根据看到的 "value1/2/3" 个项目的数量构建一个输出数组,而不是传入数组中的元素数量。例如。如果您的三个输入项根本没有定义 "value3",那么您最终的输出 "result" 数组将只有两个数组元素;一份用于 "value1" 一份用于 "value2".

此规范有效,但考虑到正在发生的事情可能会因奇怪的输入而变得脆弱。

要了解这是做什么的,我建议打开 jolt-demo 站点的 4 个浏览器选项卡,运行 每个单独的移动操作,将一个选项卡的输出复制到下一个选项卡的输入选项卡

我就是这样写的。

规格

[
  {
    "operation": "shift",
    "spec": {
      "result": {
        "*": {
          // first group all the data by valueKEY
          "value*": "&[]"
        }
      }
    }
  },
  {
    // next build the 'AAA':'AAA-111' structure
    //  but not yet in the final result array
    "operation": "shift",
    "spec": {
      "value*": { // should be value1, value2, etc
        "*": { // array index
          "*-*": {
            // keep top level value1, value2
            // but now build the 'AAA':'AAA-111' logic
            // This is assuming that it is hypen "-" delimited
            "@1": "&3.&(1,1)"
          }
        }
      }
    }
  },
  {
    // now build 'value_name':'value1'
    "operation": "shift",
    "spec": {
      "value*": {
        // pass thru the "AAA':'AAA-111' data 
        "*": "&1.&",
        //
        // push value name down to be siblings of 'AAA':'AAA-111'
        "$": "&1.value_name"
      }
    }
  },
  {
    // finally now that the core data is all setup, accumulate 
    //  into an array
    "operation": "shift",
    "spec": {
      "value*": "result[]"
    }
  }
]