A Beginner’s Guide to the Reduce Function in DataWeave

DataWeave is MuleSoft’s powerful data transformation language included in the Mule runtime. One of its most useful features is the reduce function.

The reduce function allows you to accumulate and combine values from an array into a single result. It is perfect for aggregating data and calculating metrics.

In this comprehensive guide, you will learn:

  • What is the reduce function in DataWeave?
  • How to reduce works compared to map()
  • Reducing arrays to sums, averages, and more
  • Combining reduction with filtering and mapping
  • Reducing object arrays into a single value
  • Advanced usage with functors and accumulators
  • Examples and use cases for reduction
  • How to write reusable reduce functions

By the end, you will be well-versed in applying DataWeave’s reduce function to transform and aggregate array data in Mule applications.

[/su_box]

What is the Reduce Function in DataWeave?

The reduce function applies an expression cumulatively to all elements in an array, resulting in a single value.

For example, to sum all numbers in an array:

%dw 2.0
var numbers = [1, 2, 3, 4, 5]

// Sum array
reduce numbers = $ + $$ // returns 15

Here $ refers to the cumulative value while $$ is the current element.

On each iteration, $$ is added to the total $ value ultimately aggregating the array to a sum.

Let’s compare the reduction with a map to better understand it.

How Reduce Compares to Map

DataWeave’s map function transforms each array element independently:

%dw 2.0
var names = ["John", "Sarah", "Bob"]

// Uppercase each name 
map names = $ uppercase

This returns a new array with all values modified.

Reduce instead cumulatively combines values to return a single result:

var numbers = [1, 2, 3, 4, 5]

// Sum all numbers
reduce numbers = $ + $$ 

Map transforms each element, while reduce aggregates the entire array.

Next let’s look at more examples of reducing arrays to totals, averages and other metrics.

Reducing Arrays to Sums, Averages and More

The reduce function is perfect for aggregating arrays into totals, averages, minimums and other singular values.

For example, to sum an array of numbers:

var numbers = [1, 2, 3, 4, 5] 

// Sum 
reduce numbers = $ + $$

To average them:

var numbers = [1, 2, 3, 4, 5]

// Average
reduce (numbers, sum = 0, count = 0) 
   .sum = $.sum + $$$
   .count = $.count + 1
) / $.count

Here we accumulate both a sum and count to enable calculating the mean.

You can aggregate arrays into any metric, like minimum:

var ages = [23, 62, 45, 17, 32]

// Minimum age
reduce ages = $ < $$ ? $ : $$

The key is crafting an expression to combine elements into your desired end result.

Next let’s look at using filter and map with reduce.

Combining Reduction with Filtering and Mapping

You can easily compose reduce with DataWeave’s filter and map functions for additional transformation.

For example, find the sum of even numbers:

var numbers = [1, 2, 3, 4, 5, 6]

numbers 
filter $ % 2 == 0 // Filter even
reduce $ + $$ // Sum

You can also map elements before reducing:

var transactions = [
  { amount: 10 },
  { amount: 5},
  { amount: 20}
]

transactions
map $.amount // Extract amounts
reduce $ + $$ // Sum

Chaining filter, map, and reduce provides limitless data shaping potential!

Next we’ll reduce arrays of objects.

Reducing Object Arrays into a Single Value

So far we’ve reduced simple arrays of numbers and strings. But you can also reduce arrays of objects:

var users = [
  { name: "John", age: 20 },
  { name: "Sarah", age: 25 } 
]

// Average age
users 
reduce ($$, sum = 0, count = 0) 
  .sum = $.sum + $$.age
  .count = $.count + 1
) / $.count

This aggregates object properties like age into an overall average.

You can craft reusable reduce functions to handle common object aggregations.

Advanced Usage with Functors and Accumulators

DataWeave provides some advanced reduce features for custom reductions:

Functors

A functor wraps the main reduction expression into a reusable function.

For example, a sum functor:

fun sumFunctor(x, y) = x + y

// Use functor 
[1, 2, 3].reduce(sumFunctor)

This encapsulates the core + operation as a reusable unit.

Accumulators

You can specify an initial accumulator value rather than starting from the first element:

// Start sum at 100 
[1, 2, 3].reduce(sumFunctor, 100)

Functors and accumulators enable highly customizable reduce logic.

Now let’s look at some common use cases.

Use Cases for DataWeave Reduction

Here are some examples of good use cases for DataWeave’s reduce function:

  • Summing or averaging metrics over time
  • Calculating aggregate KPIs like total revenue
  • Reducing stream aggregations using windowing
  • Combining API data from multiple pages into a report
  • Generating a hash or checksum value from strings
  • Flattening nested array structures for further processing

Any time you need to process array data into aggregated metrics or a single value, consider using reduce.

Next we’ll write some reusable reduce functions.

Writing Reusable Reduce Functions

To simplify reduction logic, you can create reusable DataWeave functions:

%function sumArray(arr)
  reduce (
    arr,
    sum = 0
  ) 
  .sum = $.sum + $$
  
%function minValue(arr)
  reduce arr = $ < $$ ? $ : $$

// Use like:
sumArray([1, 2, 3, 4])
minValue([10, 2, 30, 4])

Conclusion

In this guide, you learned:

  • The reduce function cumulatively combines array values
  • It aggregates unlike map which transforms individually
  • Reduce arrays to sums, averages, minimums, and more
  • Chain filter, map, and reduce for data pipelines
  • Reduce object arrays based on property values
  • Use functors and accumulators for advanced logic
  • Applying reduce for streaming, APIs, reporting, and more
  • Writing reusable reduce functions improves code reuse

You are now ready to harness DataWeave’s reduce function for efficient data aggregation and metrics calculation in Mule apps.

Check out the MuleSoft documentation for more details and examples of reducing arrays in DataWeave scripts.

Leave a Comment