Executando verificação de segurança...
4

Basta criar um array contendo a probabilidade de cada valor, e em seguida gere um número aleatório entre 1 e a soma das probabilidades, e percorra o array, subtraindo cada probabilidade deste número até que ele zere:

function sortear(probabilidades) {
    var min = 1;
    var max = 0; // o valor máximo é a soma das probabilidades
    for (const p of probabilidades) {
        max += p[0];
    }

    var x = Math.floor(Math.random() * (max - min + 1)) + min;
    for (const [p, valor] of probabilidades) {
        x -= p;
        if (x <= 0) {
            return valor;
        }
    }
}

const probabilidades = [
    [50, 'algum valor'],
    [15, 'outro valor'],
    [35, 'e outro']
];

console.log(sortear(probabilidades));

O raciocínio é que a probabilidade de um item é maior que a soma das probabilidades dos itens anteriores, daí vc vai subtraindo e quando ficar menor ou igual a zero, sabe que chegou na probabilidade daquele item.

No caso precisei adicionar um item com probabilidade 35%, para completar os 100%. E as probabilidades não podem estar em um objeto, pois podem ter dois valores com a mesma probabilidade. Por exemplo, se dois itens tivessem 30%, não poderia fazer probabilidades = { 30: 'um valor', 30: 'outro valor' }, pois um objeto não permite chaves duplicadas. Por isso fiz um array de arrays.

Mas note que o algoritmo é um pouco mais genérico, pois funciona com qualquer proporção (não apenas porcentagem). Por exemplo, se tiver dois itens e um tem 5 vezes mais chances de sair que o outro, bastaria trocar para:

const probabilidades = [
    [5, 'tenho 5 vezes mais chances de sair que o outro'],
    [1, 'outro']
];

Se fosse fazer com porcentagem, o primeiro item teria que ser 83.3333333333... e o segundo, 16.6666666666.... São dízimas periódicas, então o total não seria exatamente 100. Porém, usando 5 e 1, funciona da forma esperada, pois o algoritmo sempre considera a soma das "probabilidades", que na verdade funcionam mais como "pesos". A porcentagem é simplesmente um caso especial em que a soma dos pesos é 100.


Algoritmo retirado daqui.

Carregando publicação patrocinada...