Array element assignment from one segment to other when length of array is dynamic

Here is the sample challenge,
below is input and expected output.
items can increase dynamically, but the “WORK” field of REFILL should get assigned under NAME field of TOTLITEM.

input payload :
[
{
“REFILL”:{
“item”:[
{
“ITEM”:“1”,
“TEXT”:“first”,
“NAME”:“laptop”,
“WORK”:“office”
},
{
“ITEM”:“2”,
“TEXT”:“second”,
“NAME”:“mobile”,
“WORK”:“marketing”
}
]
}
},
{
“TOTLITEM”:{
“item”:[
{
“ITEM”:“1”,
“TEXT”:“first”,
“NAME”:“none”
},
{
“ITEM”:“2”,
“TEXT”:“second”,
“NAME”:“none”
}
]
}
}
]

expected output :

[
{
“REFILL”:{
“item”:[
{
“ITEM”:“1”,
“TEXT”:“first”,
“NAME”:“laptop”,
“WORK”:“office”
},
{
“ITEM”:“2”,
“TEXT”:“second”,
“NAME”:“mobile”,
“WORK”:“marketing”
}
]
}
},
{
“TOTLITEM”:{
“item”:[
{
“ITEM”:“1”,
“TEXT”:“first”,
“NAME”:“none”
“WORK”:“office”
},
{
“ITEM”:“2”,
“TEXT”:“second”,
“NAME”:“none”
“WORK”:“marketing”
}
]
}
}
]

Thanks

Hi @vaidyarm,

I assumed that you have both arrays, $REFILL and $TOTLITEM, in the same input document. Then, putting this expression in a Mapper:
$TOTLITEM.item.map((item, pos, a)=>item.extend({WORK: $REFILL.item[pos].WORK}))
and assigning it to the $TOTLITEM.item Target Path, should do what you need done.

BR,
Dimitri

2 Likes

That was quick and awesome, many thanks !! this gives an idea for all such type of transformations.

can you also suggest a solution for a case like below,
where the number of elements to be mapped subsection of the array does not matches the count of source array.

For the same input as above, below is expected output.

[
   {
      "REFILL":{
         "item":[
            {
               "ITEM":"1",
               "TEXT":"first",
               "NAME":"laptop",
               "WORK":"office"
            },
            {
               "ITEM":"2",
               "TEXT":"second",
               "NAME":"mobile",
               "WORK":"marketing"
            }
         ]
      }
   },
   {
      "TOTLITEM":{
         "item":[
            {
               "ITEM":"1",
               "TEXT":"first",
               "NAME":"none",
               "DETAILS":[
                  {
                     "LINE":"1",
                     "WORK":"office"
                  },
                  {
                     "LINE":"2",
                     "WORK":"office"
                  }
               ]
            },
            {
               "ITEM":"2",
               "TEXT":"second",
               "NAME":"none",
               "DETAILS":[
                  {
                     "LINE":"1",
                     "WORK":"marketing"
                  }
               ]
            }
         ]
      }
   }
]

being able to do this, will help a lot to handle any transformation thereafter. let me know the solution.

Hi,

If you put this mammoth of an expression :slight_smile: in a Mapper:

$TOTLITEM.item.map( (item, pos, a)=>item.extend({DETAILS: (pos != 0) ? sl.ensureArray( {}.extend({LINE:1,WORK:$REFILL.item[pos].WORK}) ) : sl.ensureArray( {}.extend({LINE:1,WORK:$REFILL.item[pos].WORK}) ).concat({}.extend({LINE:2,WORK:$REFILL.item[pos].WORK})) } ) )

and you assign it to the $TOTLITEM.item Target Path, then you will get the expected output.

There’s that. Now, this solution is static, in the sense that it exactly transforms the input into the output. That’s because without knowing the size of the nested array $DETAILS in advance, not much more can be done. But then, I feel that the solution wouldn’t be so compact, in the sense that it will more than likely require a few more snaps for the transformation to be proper.

Let me know if you have any other questions.
Cheers,

Dimitri

2 Likes

I appreciate you for coming up with the above solution, I could sense the approach you taken to tackle such complex mappings.
I would explore if the dynamic size of the array could go with the extended map function used above.

Thanks