Mapping Question... Map to dynamic names?

I have source data that looks like below, with certain “known” fields with values, and then an array of “custom” data with name/value fields:

knownfield1: value1
knownfield2: value2
knownfield3: value3
customDataSets:
  customData:
    name: customname1
    value: customvalue1
  customData:
    name: customname2
    value: customvalue2
  customData:
    name: customname3
    value: customvalue3

I would like to map this data into a common format with all fields/values, like below:

metadata:
  knownfield1: value1
  knownfield2: value2
  knownfield3: value3
  customname1: customvalue1
  customname2: customvalue2
  customname3: customvalue3

The known fields are pretty easy to deal with, but this array of separate name/value fields is giving me a hard time, especially with regards to the “target path” in the mapper not being able to be an expression where the name of the output is dynamic, only the value.

Any thoughts?

The extend() method on objects can help you construct objects dynamically. You can pass it an array of key/value pairs and it will create a new object containing the values from the original object plus whatever was specified by the pairs.

In your case, I think you can create the pairs by doing a map over the customDataSets array, like so:

$customDataSets.map(x => [x.customData.name, x.customData.value])

You can then extend the original input doc, to create a new doc containing the original stuff, plus the custom keys:

$.extend($customDataSets.map(x => [x.customData.name, x.customData.value]))

Use a target path of ‘$’ to pass the object as the whole output. But, it looks like you’ll need another mapper to delete the customDataSets if you do that.

Thanks, that helped!