I am starting with an object having two values that are arrays. For each one I want to match all non-array values with the array values but with the index values in order e.g, index zero from each array, index 1 from each array, etc.:
The object:
{
"taxedLineItems": [
{
"taxCodeNo": [
"39050",
"39051"
],
"invoiceLink": "20265654",
"lineItemNo": 99274137,
"taxCode": [
"VAT-A6",
"Other"
]
},
{
"taxCodeNo": [
"39050",
"39051"
],
"invoiceLink": "20265654",
"lineItemNo": 99274137,
"taxCode": [
"VAT-A6",
"Other"
]
},
{
"taxCodeNo": [
"39050",
"39051"
],
"invoiceLink": "20265656",
"lineItemNo": 99274142,
"taxCode": [
"VAT-A6",
"Other"
]
},
{
"taxCodeNo": [
"39050",
"39051"
],
"invoiceLink": "20265656",
"lineItemNo": 99274142,
"taxCode": [
"VAT-A6",
"Other"
]
}
]
}
I am wanting to "flatten" it so that all the combinations are expressed with no array values - desired output:
{
"taxedLineItems": [
{
"taxCodeNo": "39050",
"invoiceLink": "20265654",
"lineItemNo": 99274137,
"taxCode": "VAT-A6"
},
{
"taxCodeNo": "39051",
"invoiceLink": "20265654",
"lineItemNo": 99274137,
"taxCode": "Other"
},
{
"taxCodeNo": "39050",
"invoiceLink": "20265656",
"lineItemNo": 99274142,
"taxCode": "VAT-A6"
},
{
"taxCodeNo": "39051",
"invoiceLink": "20265656",
"lineItemNo": 99274142,
"taxCode": "Other"
}
]
}
I have tried and failed with various $map attempts, etc. One failed attempt:
{
"taxedLineItemDetails":
$.taxedLineItems.$map(taxCode, function($v, $i, $a) {
{
"invoiceLink":$$.taxedLineItems[$i].invoiceLink,
"lineItemNo":$$.taxedLineItems[$i].lineItemNo,
"taxCode":$v }
})
}
Some advice please!
The following is one option:
{
"taxedLineItems":$reduce(
$map($distinct(taxedLineItems.invoiceLink), function($link, $linkIndex) {
$map($filter(taxedLineItems, function($v, $i) {$v.invoiceLink = $link}), function($item, $itemIndex) {
{
"taxCodeNo": $item.taxCodeNo[$itemIndex],
"invoiceLink": $item.invoiceLink,
"lineItemNo": $item.lineItemNo,
"taxCode": $item.taxCode[$itemIndex]
}
})
}), $append)
}
With the following parts:
This identifies the unique invoiceLink
s:
$distinct(taxedLineItems.invoiceLink)
Mapping over those with:
$map($filter(taxedLineItems, function($v, $i) {$v.invoiceLink = $link})...
Will allow just dealing with the objects that relate to the invoiceLink
.
Then the $itemIndex
is relevant to the arrays for taxCodeNo
and taxCode
:
{
"taxCodeNo": $item.taxCodeNo[$itemIndex],
"invoiceLink": $item.invoiceLink,
"lineItemNo": $item.lineItemNo,
"taxCode": $item.taxCode[$itemIndex]
}
The wrapper of:
$reduce(..., $append)
Is per this link.
Working example:
(async function () {
const transform = `{
"taxedLineItems":$reduce(
$map($distinct(taxedLineItems.invoiceLink), function($link, $linkIndex) {
$map($filter(taxedLineItems, function($v, $i) {$v.invoiceLink = $link}), function($item, $itemIndex) {
{
"taxCodeNo": $item.taxCodeNo[$itemIndex],
"invoiceLink": $item.invoiceLink,
"lineItemNo": $item.lineItemNo,
"taxCode": $item.taxCode[$itemIndex]
}
})
}), $append)
}`;
const result = await jsonata(transform).evaluate(obj);
console.log(result);
})()
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdn.jsdelivr.net/npm/jsonata/jsonata.min.js"></script>
<script>
const obj = {
"taxedLineItems": [
{
"taxCodeNo": [
"39050",
"39051"
],
"invoiceLink": "20265654",
"lineItemNo": 99274137,
"taxCode": [
"VAT-A6",
"Other"
]
},
{
"taxCodeNo": [
"39050",
"39051"
],
"invoiceLink": "20265654",
"lineItemNo": 99274137,
"taxCode": [
"VAT-A6",
"Other"
]
},
{
"taxCodeNo": [
"39050",
"39051"
],
"invoiceLink": "20265656",
"lineItemNo": 99274142,
"taxCode": [
"VAT-A6",
"Other"
]
},
{
"taxCodeNo": [
"39050",
"39051"
],
"invoiceLink": "20265656",
"lineItemNo": 99274142,
"taxCode": [
"VAT-A6",
"Other"
]
}
]
}
</script>