Как сгладить массив JSON в файл csv

У меня есть входящая полезная нагрузка в формате JSON, из которой я вывожу некоторые объекты в файл CSV. Полезная нагрузка также имеет один массив:

      "Chargebacks": [
        {
          "CostCenterCode": "123ABC",
          "AllocationPercentage": 100
        },
        {
            "CostCenterCode": "456DEF",
            "AllocationPercentage": 100
        }
      ]

Мне нужно, чтобы CSV-файл содержал:

<other headers from the objects>,Cost Center Code 1, Allocation Percentage 1, Cost Center Code 2, Allocation Percentage 2
<other object values>,123ABC,100,456DEF,100

Моя первая попытка заключалась в создании двух переменных для хранения списка заголовков и списка значений:

%dw 2.0
output application/csv
var x = payload.Item.CatalogAttributes.Chargebacks map (chargeBack, index) -> 
{
    "header": "Cost Center Code " ++ index+1 ++ ", Allocation Percentage "++ index+1,
    "costCenterCode": chargeBack.CostCenterCode ++ "," ++ chargeBack.AllocationPercentage,
}
var foo = x.*header joinBy ','
var bar = x.*costCenterCode joinBy ','
---

и добавляем их в конец файла:

foo: bar

и вроде работает. Я получаю значение foo в конце заголовков и 123ABC\,100\,456DEF\,100 в конце значений. Как мне получить фактическое значение foo и удалить косые черты из значений?


person Count Boxer    schedule 14.01.2021    source источник


Ответы (1)


В своем ответе я предполагаю, что вы, возможно, не знаете заранее, сколько существует элементов возвратного платежа. Это dataweave:

%dw 2.0
output application/csv
---
payload map {
    ($ - "Chargebacks"),
    ($.Chargebacks map {
        ("CostCenterCode_$($$)": $.CostCenterCode),
        ("AllocationPercentage_$($$)": $.AllocationPercentage)
    })
}

используя этот пример ввода:

[
    {
        "field1": "someValue",
        "field2": "someValue",
        "Chargebacks": [
            {
                "CostCenterCode": "123ABC",
                "AllocationPercentage": 100
            },
            {
                "CostCenterCode": "456DEF",
                "AllocationPercentage": 100
            }
        ]
    },
    {
        "field1": "someValue2",
        "field2": "someValue2",
        "Chargebacks": [
            {
                "CostCenterCode": "123ABC2",
                "AllocationPercentage": 200
            },
            {
                "CostCenterCode": "456DEF2",
                "AllocationPercentage": 200
            }
        ]
    }
]

создает этот csv:

field1,field2,CostCenterCode_0,AllocationPercentage_0,CostCenterCode_1,AllocationPercentage_1
someValue,someValue,123ABC,100,456DEF,100
someValue2,someValue2,123ABC2,200,456DEF2,200

Оборачивая нашу карту в _4 _..._ 5_, мы в основном говорим ей взять результирующий массив и сгладить его до объекта верхнего уровня. Если вы знакомы, это очень похоже на оператор распространения в javascript. $ и $$ являются сокращениями для функции. Например, если у вас есть такая функция: fun someFun(left, fn: (item, index) -> Any), вы можете вызвать ее, используя этот шаблон payload someFun ..., где полезная нагрузка становится параметром left, а затем правая часть становится функцией; каждый параметр, переданный в функцию, становится $, где количество $ - это позиция параметра. Есть смысл? Обратите внимание, что этот шаблон вызова функций не ограничивается тем, который принимает функцию. Например, вы можете создать такую ​​функцию: fun add(left, right) = left + right и называть ее так 1 add 2. Это работает только при использовании ключевого слова fun и когда у вас есть ровно два параметра.

Если вы собираетесь иметь потенциально нестандартные размеры (например, у некоторых может быть больше, чем у других) и вам нужны пустые записи для более мелких элементов, вам нужно заранее определить максимальный размер и сделать что-то вроде этого:

%dw 2.0
output application/csv
var maxSize = max(payload map sizeOf($.Chargebacks))
---
payload map (row) -> {
    (row - "Chargebacks"),
    ((1 to maxSize) map {
        ("CostCenterCode_$($$)"): row.Chargebacks[$$].CostCenterCode,
        ("AllocationPercentage_$($$)"): row.Chargebacks[$$].AllocationPercentage
    })
}

Это отобразит ввод, подобный этому:

[
    {
        "field1": "someValue",
        "field2": "someValue",
        "Chargebacks": [
            {
                "CostCenterCode": "123ABC",
                "AllocationPercentage": 100
            },
            {
                "CostCenterCode": "456DEF",
                "AllocationPercentage": 100
            },
            {
                "CostCenterCode": "456DEF",
                "AllocationPercentage": 100
            }
        ]
    },
    {
        "field1": "someValue2",
        "field2": "someValue2",
        "Chargebacks": [
            {
                "CostCenterCode": "123ABC2",
                "AllocationPercentage": 200
            },
            {
                "CostCenterCode": "456DEF2",
                "AllocationPercentage": 200
            }
        ]
    }
]

к этому:

field1,field2,CostCenterCode_0,AllocationPercentage_0,CostCenterCode_1,AllocationPercentage_1,CostCenterCode_2,AllocationPercentage_2
someValue,someValue,123ABC,100,456DEF,100,456DEF,100
someValue2,someValue2,123ABC2,200,456DEF2,200,,
person Michael Jones    schedule 14.01.2021
comment
Чистая элегантность! Рабочий код и подробное объяснение. - person Count Boxer; 15.01.2021