Вы можете взять замыкание по массиву весов со всеми весами и вернуть функцию, которая получает индекс, основанный на сумме всех весов.
function getWeightedDistribution(weights) {
return function () {
var random = Math.random(),
sum = 0;
return weights.findIndex(w => random < (sum += w));
};
}
var weights = [0.1, 0.25, 0.25, 0.4], // all values have to sum to 1
i;
weightFunction = getWeightedDistribution(weights),
counts = [0, 0, 0, 0];
for (i = 0; i < 1e6; i++) counts[weightFunction()]++;
console.log(...counts);
Вместе с вашим кодом
function getWeightedDistribution(weights) { // weights sums up to 1
return function () {
var random = Math.random(),
sum = 0;
return weights.findIndex(w => random < (sum += w));
};
}
var item = [{ verDiv: 'div-gpt-ad-1553003087342-0', verKv: 'version1', verSize: [300, 250], weight: 10 }, { verDiv: 'div-gpt-ad-1553003087342-1', verKv: 'version2', verSize: [300, 250], weight: 25 }, { verDiv: 'div-gpt-ad-1553003087342-2', verKv: 'version3', verSize: [160, 600], weight: 25 }, { verDiv: 'div-gpt-ad-1553003087342-3', verKv: 'version4', verSize: [728, 90], weight: 40 }],
weightFunction = getWeightedDistribution(item.map(({ weight }) => weight / 100));
console.log(item[weightFunction()].verDiv);
console.log(item[weightFunction()].verKv);
console.log(item[weightFunction()].verSize);