I'm converting an array of objects to an object of key:value pairs, where the value is an string aggregation. My challenge is that I do not now how to access obj properties, while using reduce ( (env,obj={})
Currently I can weave the following payload:
{
"records": [{
"MetadataComponentName": "ClassB",
"RefMetadataComponentName": "ClassC"
},{
"MetadataComponentName": "ClassA",
"RefMetadataComponentName": "ClassB"
}
]
}
to
{
"ClassB": "ClassC",
"ClassA": "ClassB",
}
But the goal is to achieve:
{
"ClassA": "ClassB,ClassC",
}
The script is:
%dw 2.0
output application/json
---
payload.records reduce (
(env,obj={}) ->
obj ++ {
(env.MetadataComponentName):env.RefMetadataComponentName
}
)
And I've tested accessing obj in a conditional as follows:
%dw 2.0
output application/json
---
payload.records reduce (
(env,obj={}) ->
if ((obj['MetadataComponentName']=="ClassB"))
obj ++ {
(env.MetadataComponentName):env.RefMetadataComponentName
}
else null
)
which produces a null result! Negating the conditional - if (!(obj['MetadataComponentName']=="ClassB")) obj ++ {
produces the same output as without the conditional at all.
My intended logic would be to ultimately prevent deduplicating keys:
if (!(obj['MetadataComponentName']==env.MetadataComponentName))
obj ++ {
(env.MetadataComponentName):env.RefMetadataComponentName
}
else
(env.MetadataComponentName): obj['MetadataComponentName'] + env.RefMetadataComponentName
Questions:
obj['MetadataComponentName']
the correct syntax to retrieve a value?Thoughts and opinions much appreciated.
Note that reduce works on arrays, and the state it keeps is just an accumulator and the current element. I don't understand why do see a limitation on accessing the properties of the object. Your scripts access the properties correctly in different ways.
It looks just that you are trying to use reduce() in a way that is not well matched to it. I recommend to keep it simple and use reduce to accumulate the values you need in an easy way to operate, then transform that in the expected result.
Example:
%dw 2.0
output application/json
var result=payload.records
reduce (
(env,obj={lastKey: null, names:[]}) ->
{
lastKey: env.MetadataComponentName,
names: ([env.RefMetadataComponentName] ++ obj.names)
}
)
---
{ (result.lastKey): result.names joinBy ","}
Output:
{
"ClassA": "ClassB,ClassC"
}
The result is what was asked. I'm not sure if the algorithm I used is the one you want because the logic that you were trying to achieve was not clarified in the question.
Using obj.MetadataComponentName
and obj['MetadataComponentName']
give the same result. The second form is the dynamic selector one usually used with the index being expressions or variables rather than literal strings.