Created
June 29, 2022 11:17
-
-
Save bennadel/cbab646778a79410c4f394bf40625a51 to your computer and use it in GitHub Desktop.
Using An Array To Power Weighted Distributions In Lucee CFML 5.3.8.201
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfscript> | |
// Our build-function is going to return a generator function that produces values | |
// with the given weighted frequencies. | |
next = buildWeightedDistribution([ | |
{ value: "a", percent: 10 }, | |
{ value: "b", percent: 20 }, | |
{ value: "c", percent: 70 } | |
]); | |
// By outputting 100 values, we should see occurrences that roughly match the defined | |
// percentages from above. | |
loop times = 100 { | |
echo( next() & " " ); | |
} | |
// ------------------------------------------------------------------------------- // | |
// ------------------------------------------------------------------------------- // | |
/** | |
* I return a function that will produce values with the given distribution. Each entry | |
* is expected to have two properties: | |
* | |
* - value: the value returned by the generator. | |
* - percent: the weight (0-100) of the value in the distribution. | |
*/ | |
public function function buildWeightedDistribution( required array distributions ) { | |
var index = []; | |
var indexSize = 0; | |
// In order to make it super easy to generate the next value in our series, we're | |
// going to pre-compute an array in which each value is repeated as many times as | |
// is required by its weight. So, a value that is supposed to be returned 30% of | |
// the time will be repeated 30 times in our internal index. | |
for ( var distribution in distributions ) { | |
loop times = distribution.percent { | |
index[ ++indexSize ] = distribution.value; | |
} | |
} | |
// Now that we have our internal index of repeated values, our generator function | |
// simply has to pick a random value from the index. | |
return( | |
() => { | |
return( index[ randRange( 1, indexSize, "SHA1PRNG" ) ] ); | |
} | |
); | |
} | |
</cfscript> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment