Master DataWeave Weighted Random Generation: A Step-by-Step Guide

Ever needed to create test data that actually mimics real-life scenarios? Sometimes, a purely random list isn't enough. You need "weighted" randomness—think of it like a loaded die where one side comes up more often than the others, or a lottery where one person holds 60 tickets while another holds only 20.


In this guide, I’ll walk you through using DataWeave (DWL) to generate a list of random codes based on specific probabilities. This is incredibly useful for sampling, stress testing, and statistical modeling within your MuleSoft applications.

The Scenario: Setting Up the Probability

Before we dive into the logic, let's look at our input. We are working with a JSON array where every object has two specific fields: a code and a probability.

Think of the probability as a percentage. In the example below, we have three codes:

  • ABC: 60% chance (Most frequent)
  • DEF: 20% chance
  • HIJ: 20% chance

Here is the Input Data structure:

var fileData = [
 {"code": "ABC","probability": 60
 },
 {"code": "DEF","probability": 20
 },
 {"code": "HIJ","probability": 20
 }
]

The Logic: Creating the Distribution

Now, let's write the DataWeave Weighted Random Generation script. The goal here is to produce a list of 1000 codes. To do this, we need to calculate exactly how many times each code should appear based on its percentage, create those items, and then shuffle them up.

We will utilize the dw::core::Arrays module and functions like map, flatten, and orderBy.

The Breakdown

  1. Calculate Counts: We determine how many items are needed (e.g., 60% of 1000 is 600 items).
  2. Generate Lists: We create arrays containing the code repeated that specific number of times.
  3. Shuffle: We use orderBy random() to mix the sorted list into a random distribution.

Here is the complete DataWeave Script:

%dw 2.0
import * from dw::core::Arrays
output application/json
var fileData = [
 {
"code": "ABC",
"probability": 60
 },
 {
"code": "DEF",
"probability": 20
 },
 {
"code": "HIJ",
"probability": 20
 }
]
var codes = fileData.code
var percentage = fileData.probability
var maxreq = 1000
var multiply_items = percentage map ((item) -> (((item default 0) * maxreq) / 100) as Number)
var total_codes = flatten(multiply_items map ((item, index) -> (0 to item-1) map ((i) -> codes[index])
))
---
multiply_items flatMap(
if($ < 1) [] else ((0  to $-1) map ((item, index) -> codes[$$] ))
) orderBy random()

The Result: Verifying the Output

When you run the script above, DataWeave generates a single JSON array containing 1000 entries. Because we used orderBy random(), the order is unpredictable, but the frequency respects your input rules. You will notice that "ABC" appears significantly more often than "DEF" or "HIJ."

Sample Output:

["ABC","ABC","HIJ","ABC","DEF","ABC","ABC","ABC","DEF","ABC",
 ...
]

Bonus: The Optimized Script

If you want to keep your code concise, here is a streamlined version of the logic. It achieves the exact same result—generating DataWeave Weighted Random Generation lists—but combines the calculation and generation steps into a cleaner flow using flatMap.

Bonus Script:

%dw 2.0
import * from dw::core::Arrays
output application/json
var fileData = [
 {
"code": "ABC",
"probability": 60
 },
 {
"code": "DEF",
"probability": 20
 },
 {
"code": "HIJ",
"probability": 20
 }
]
var maxRequest = 1000
---
fileData flatMap(
1 to (($.probability / 100) * maxRequest) map ((item, index) -> $.code)
) orderBy random()

Conclusion

And there you have it! We successfully used DataWeave to generate a dataset that respects probability rules rather than pure chaos. Whether you are working with JSON, XML, or CSV, this logic provides a robust way to create realistic simulation data for your testing needs.

Post a Comment (0)
Previous Post Next Post