2

I try to get my head around the reduce function in Mulesoft Dataweave 2.0.

expected outcome:

{
  "dev": "1",
  "test": "2",
  "uat": "3",
  "prod": "4"
}

my dataweave code:

%dw 2.0
var invar = [
  {"id": "1", "name": "dev"},
  {"id": "2", "name": "test"},
  {"id": "3", "name": "uat"},
  {"id": "4", "name": "prod"}
]
output application/json
---
// invar reduce() ???  requirment: it must be done with reduce function.

Thanks

aled
  • 21,330
  • 3
  • 27
  • 34
Ben
  • 594
  • 1
  • 9
  • 24
  • There is an answer [here](https://stackoverflow.com/questions/60133645/how-do-you-convert-sql-server-select-into-xml-in-mule-4/60140222#60140222) that I explain `reduce` – George Dec 25 '20 at 21:59

4 Answers4

6

The trick is to set the accumulator to the correct value when DataWeave can not deduce it automatically:

%dw 2.0
var invar = [
  {"id": "1", "name": "dev"},
  {"id": "2", "name": "test"},
  {"id": "3", "name": "uat"},
  {"id": "4", "name": "prod"}
]
output application/json
---
invar reduce ((item, accumulator= {}) -> accumulator ++ {(item.name):item.id})
aled
  • 21,330
  • 3
  • 27
  • 34
  • Thanks Aled, Still can not get my head around this why this works. Because when you do a concatenate it adds strings together. So Dataweave "knows" when the index parameter of the reduce = {} that the result must be between curly brackets. Right ? – Ben Dec 24 '20 at 15:31
  • 3
    reduce() operate on arrays, but the concatenate operation ´++´ can operate on arrays, strings, objects and several types of dates combinations. Because I set the accumulator to an object and the second parameter of concatenation is another object, it does an object concatenation as described at https://docs.mulesoft.com/mule-runtime/4.3/dw-core-functions-plusplus#plusplus3 – aled Dec 24 '20 at 17:59
  • 1
    Exactly, the ++ function is overloaded for different DataWeave types. – Ethan Port Jan 03 '22 at 08:15
0

Initialise accumulator to empty object {} and add the formed key value pairs to the accumulator for the required output:

invar reduce ((item, accumulator = {}) -> accumulator ++ {(item.name): item.id } )

0

Reduce works on Array and keep accumulating each array iteration and return once processing is done. In your example, I initialize the accumulator with empty object {}, and in every iteration, I use item.name as the object key and item.id as the value.

var invar = [
  {"id": "1", "name": "dev"},
  {"id": "2", "name": "test"},
  {"id": "3", "name": "uat"},
  {"id": "4", "name": "prod"}
]
output application/json
---
invar reduce ((item, accumulator={}) -> accumulator ++ {
    (item.name) : item.id
})
0
%dw 2.0
var invar = [
  {"id": "1", "name": "dev"},
  {"id": "2", "name": "test"},
  {"id": "3", "name": "uat"},
  {"id": "4", "name": "prod"}
]
output application/json
---
invar reduce ((item, acc = {}) -> acc ++ {(item.name) : item.id})