Transform complex structures to array of objects

Hi,

I would like to transform complex structures to an simple array with objects.

In the dataset below, I want each value in values.*.*.data to be an new entry in the result array, combined with keys and values from their parent object.

Input:

{
    "values": {
        "image_type_1": [
            {
                "locale": "en_US",
                "data": [
                    "image_type1_en_1.jpg",
                    "image_type1_en_2.jpg"
                ]
            }
        ],
        "image_type_2": [
            {
                "locale": "en_US",
                "data": [
                    "image_type2_en_1.jpg",
                    "image_type2_en_2.jpg"
                ]
            },
            {
                "locale": "nl_NL",
                "data": [
                    "image_type2_nl_1.jpg",
                    "image_type2_nl_2.jpg"
                ]
            }
        ]
    }
}

Desired output:

{
    "result": [
        {
            "type": "image_type_1",
            "locale": "en_US",
            "asset": "image_type1_en_1.jpg"
        },
        {
            "type": "image_type_1",
            "locale": "en_US",
            "asset": "image_type1_en_2.jpg"
        },
        {
            "type": "image_type_2",
            "locale": "en_US",
            "asset": "image_type2_en_1.jpg"
        },
        {
            "type": "image_type_2",
            "locale": "en_US",
            "asset": "image_type2_en_2.jpg"
        },
        {
            "type": "image_type_2",
            "locale": "nl_NL",
            "asset": "image_type2_nl_1.jpg"
        },
        {
            "type": "image_type_2",
            "locale": "nl_NL",
            "asset": "image_type2_nl_2.jpg"
        },
    ]
}

Any help would be appreciated!

Hi @daniellefers

There are a few steps need to be done to achieve your objective.

First, as it will require a chain of multiple entity transformers, you should put Chain multiple entity transformers as the root of your entity transformer.

Next, as you can see that the image types (image_type_1 and image_type_2) are keys in the associative array values. In order to move it to a value, you should use Move data between accessors.

Based on the above transformer, the image types are now a value of type key and the previous value will be set as a value of data property.

{
  "values": [
    {
      "type": "image_type_1",
      "data": [
        {
          "locale": "en_US",
          "data": [
            "image_type1_en_1.jpg",
            "image_type1_en_2.jpg"
          ]
        }
      ]
    },
    {
      "type": "image_type_2",
      "data": [
        {
          "locale": "en_US",
          "data": [
            "image_type2_en_1.jpg",
            "image_type2_en_2.jpg"
          ]
        },
        {
          "locale": "nl_NL",
          "data": [
            "image_type2_nl_1.jpg",
            "image_type2_nl_2.jpg"
          ]
        }
      ]
    }
  ]
}

Then, you should transform the data array that contains the image filenames into an array of objects. You can use Move using a pattern to do so.

It will result in the below entity, where each image filename is now a value of key asset in each object of the array.

{
  "values": [
    {
      "type": "image_type_1",
      "data": [
        {
          "locale": "en_US",
          "data": [
            {
              "asset": "image_type1_en_1.jpg"
            },
            {
              "asset": "image_type1_en_2.jpg"
            }
          ]
        }
      ]
    },
    {
      "type": "image_type_2",
      "data": [
        {
          "locale": "en_US",
          "data": [
            {
              "asset": "image_type2_en_1.jpg"
            },
            {
              "asset": "image_type2_en_2.jpg"
            }
          ]
        },
        {
          "locale": "nl_NL",
          "data": [
            {
              "asset": "image_type2_nl_1.jpg"
            },
            {
              "asset": "image_type2_nl_2.jpg"
            }
          ]
        }
      ]
    }
  ]
}

You should now copy the image type to each asset object we created above. Since you have more than one image type in each object of array values, and you may have more in the actual case, you should use Node, transform nodes to loop into the values array. Then, use Recursively copy values to children.

Now, each object that contains asset (image filename) will have the image type as well.

[
  {
    "values": [
      {
        "type": "image_type_1",
        "data": [
          {
            "locale": "en_US",
            "data": [
              {
                "asset": "image_type1_en_1.jpg",
                "type": "image_type_1"
              },
              {
                "asset": "image_type1_en_2.jpg",
                "type": "image_type_1"
              }
            ]
          }
        ]
      },
      {
        "type": "image_type_2",
        "data": [
          {
            "locale": "en_US",
            "data": [
              {
                "asset": "image_type2_en_1.jpg",
                "type": "image_type_2"
              },
              {
                "asset": "image_type2_en_2.jpg",
                "type": "image_type_2"
              }
            ]
          },
          {
            "locale": "nl_NL",
            "data": [
              {
                "asset": "image_type2_nl_1.jpg",
                "type": "image_type_2"
              },
              {
                "asset": "image_type2_nl_2.jpg",
                "type": "image_type_2"
              }
            ]
          }
        ]
      }
    ]
  }
]

The remaining value to be copied is locale, which requires the same way as the previous one but with different pattern of the Node, transform nodes and the pattern of the Recursively copy values to children.

Then, you will have all the data you need in each object.

{
  "values": [
    {
      "type": "image_type_1",
      "data": [
        {
          "locale": "en_US",
          "data": [
            {
              "asset": "image_type1_en_1.jpg",
              "type": "image_type_1",
              "locale": "en_US"
            },
            {
              "asset": "image_type1_en_2.jpg",
              "type": "image_type_1",
              "locale": "en_US"
            }
          ]
        }
      ]
    },
    {
      "type": "image_type_2",
      "data": [
        {
          "locale": "en_US",
          "data": [
            {
              "asset": "image_type2_en_1.jpg",
              "type": "image_type_2",
              "locale": "en_US"
            },
            {
              "asset": "image_type2_en_2.jpg",
              "type": "image_type_2",
              "locale": "en_US"
            }
          ]
        },
        {
          "locale": "nl_NL",
          "data": [
            {
              "asset": "image_type2_nl_1.jpg",
              "type": "image_type_2",
              "locale": "nl_NL"
            },
            {
              "asset": "image_type2_nl_2.jpg",
              "type": "image_type_2",
              "locale": "nl_NL"
            }
          ]
        }
      ]
    }
  ]
}

However, since you need all the objects merged into an array, you will need a help from JMESPath to do so.

Finally, you will have a new property called result that contains the array of objects you wants to achieve.

{
  "result": [
    {
      "asset": "image_type1_en_1.jpg",
      "type": "image_type_1",
      "locale": "en_US"
    },
    {
      "asset": "image_type1_en_2.jpg",
      "type": "image_type_1",
      "locale": "en_US"
    },
    {
      "asset": "image_type2_en_1.jpg",
      "type": "image_type_2",
      "locale": "en_US"
    },
    {
      "asset": "image_type2_en_2.jpg",
      "type": "image_type_2",
      "locale": "en_US"
    },
    {
      "asset": "image_type2_nl_1.jpg",
      "type": "image_type_2",
      "locale": "nl_NL"
    },
    {
      "asset": "image_type2_nl_2.jpg",
      "type": "image_type_2",
      "locale": "nl_NL"
    }
  ]
}

We hope our explanation is clear to you. Please give it a try and let us know if you find any issues.