Объединение значений из двух массивов в DataWeave

#json #dataweave #mulesoft

#json #dataweave #mulesoft

Вопрос:

Я только начинаю работать с Dataweave и пытаюсь понять, как преобразовать данные из этого конкретного ответа JSON. Я в тупике после довольно исчерпывающего чтения документации и поиска примеров. Не могу найти ничего похожего. Ниже приведена полезная нагрузка, с которой я работаю:

 [
  {
    "columnMetadata": [
      {
        "name": "shape",
        "columnIndex": 0,
        "dataType": "string",
        "schemaType": "Static"
      },
      {
        "name": "color",
        "columnIndex": 1,
        "dataType": "string",
        "schemaType": "Static"
      }
    ],
    "rowData": [
      [
        "square",
        "yellow"
      ],
      [
        "circle",
        "green"
      ],
      [
        "star",
        "blue"
      ]
    ]
  }
]
  

Преобразование, которого я пытаюсь достичь, как таковое:

 [
    {
        "shape": "square",
        "color": "yellow"
    },
    {
        "shape": "circle",
        "color": "green"
    },
    {
        "shape": "star",
        "color": "blue"
    }
]
  

Любая помощь очень ценится!

Ответ №1:

Способ решения этой проблемы заключается в использовании динамических объектов. Эта функция позволяет динамически создавать объект из других объектов или массивировать объекты в этом случае. Это похоже на оператор распространения в js.

 %dw 2.0
output application/json
---
payload flatMap ((item, index) -> do {
    var metadataNames =  item.columnMetadata map ((metadata, index) ->  metadata.name)
    ---
    item.rowData map ((datas, index) -> 
        {
            (
                datas map ((data, index) -> 
                    {
                        (metadataNames[index]):data
                    }
                )
            )
        }
    )
})
  

Комментарии:

1. Да, это сработало, конечно же! Спасибо за ответ и ссылку на документацию.

Ответ №2:

Это преобразование должно работать, чтобы получить ваш результат

 payload..rowData flatMap (v) -> (v map ({shape: $[0], color: $[1]}))
  

Ответ №3:

Если я правильно понимаю, вы хотели выбрать данные из rowData, следуя информации, найденной в columnMetadata (конкретная информация будет выбрана на основе ColumnIndex, а ключ будет основан на имени, т.е. Форма должна исходить из rowData[0] как columnMetadata.ColumnIndex равно 0 и columnMetada.name является формой). Это будет означать, что любая информация в columnMetadata будет влиять на то, как вы читаете rowData.

Вы можете достичь этого, используя комбинацию map и reduce. Уменьшите, чтобы повторить значения вашего columnMetadata и накопить результат, и сопоставьте, чтобы выполнить уменьшение для каждого элемента ваших rowData.

Смотрите ниже dataweave:

 %dw 2.0
output application/json

---
using (columnMetadata = flatten(payload.columnMetadata))
flatten(payload.rowData) map (row) -> columnMetadata reduce ((item, acc={}) -> acc    {(item.name): row[item.columnIndex]})
  

Это приведет к:

 [
  {
    "shape": "square",
    "color": "yellow"
  },
  {
    "shape": "circle",
    "color": "green"
  },
  {
    "shape": "star",
    "color": "blue"
  }
]
  

Комментарии:

1. Имейте в виду, что сокращение не является ленивым и влияет на производительность, если это большая полезная нагрузка. Он должен использовать всю полезную нагрузку, которой не было бы в случае map .

2. Это правильно, сокращение будет иметь некоторые накладные расходы с точки зрения производительности. Однако я не вижу смысла, почему нам нужно сравнивать reduce и map, учитывая контекст моего ответа, поскольку вы не сможете выполнить это, используя только map.