Как получить случайное вознаграждение с помощью rate

#javascript

#javascript

Вопрос:

как рандомизировать по ставке, я получил 0,1% рандома, но все равно получил награду 1 Что я должен сделать, чтобы получить ее полностью случайным образом?

 var Reward = [
    {
        "Text": "Reward 1",
        "Rate": 60
    },
    {
        "Text": "Reward 2",
        "Rate": 0.5
    },
    {
        "Text": "Reward 3",
        "Rate": 0.1
    },
];

for (i = 0; i < Reward.length; i  ) {
    var result = ((Math.random() * (100 - 0))   0).toFixed(2);
    if (result <= Reward[i].Rate) {
        console.log(Reward[i].Text);
        break;
    }
}
 

Комментарии:

1. измените порядок вашего списка вознаграждений. с вашим примером 0.1% всегда <= лучше, чем 60% так, что другого ответа не будет.

Ответ №1:

 const Reward = [
    {
        "Text": "Reward 1",
        "Rate": 60
    },
    {
        "Text": "Reward 2",
        "Rate": 0.5
    },
    {
        "Text": "Reward 3",
        "Rate": 0.1
    },
]

const numProps = Object.keys(Reward).length
const ranNum = Math.floor(Math.random() * Math.floor(numProps))
console.log(`Random number was ${ranNum   1}, ${Reward[ranNum].Text} with a rate of ${Reward[ranNum].Rate}%`) 

Ответ №2:

Вы ищете число, которое <= больше числа, хранящегося в списке, и список уменьшает его значения.

Итак, вам нужно изменить порядок хранения значений в списке или порядок поиска по этому списку.

Смотрите следующий фрагмент с перевернутым списком и тестами для каждой награды:

 var Reward = [
    {
        "Text": "Reward 3",
        "Rate": 0.1
    },
    {
        "Text": "Reward 2",
        "Rate": 0.5
    },
    {
        "Text": "Reward 1",
        "Rate": 60
    },
    
];

for (i = 0; i < Reward.length; i  ) {
    var result = 0.1;
    if (result <= Reward[i].Rate) {
        console.log(Reward[i].Text);
        break;
    }
}

for (i = 0; i < Reward.length; i  ) {
    var result = 0.3;
    if (result <= Reward[i].Rate) {
        console.log(Reward[i].Text);
        break;
    }
}

for (i = 0; i < Reward.length; i  ) {
    var result = 48;
    if (result <= Reward[i].Rate) {
        console.log(Reward[i].Text);
        break;
    }
} 

Ответ №3:

Если вам нужен только один случайный элемент из массива Reward s:

 var result = Reward[Math.floor(Math.random() * Reward.length];
 

Это можно абстрагировать, так что вот так:

 var randomEntry = items => items[Math.floor(Math.random() * items.length)];

randomEntry(Reward);
 

Рабочий пример:

 const Reward = [
    {
        "Text": "Reward 1",
        "Rate": 60
    },
    {
        "Text": "Reward 2",
        "Rate": 0.5
    },
    {
        "Text": "Reward 3",
        "Rate": 0.1
    },
]

const randomEntry = items => items[Math.floor(Math.random() * items.length)];

const item = randomEntry(Reward);
console.log(`Got reward with text ${item.Text} and rate ${item.Rate}`); 


Примечания

Сложность

Эта строка:

 var result = ((Math.random() * (100 - 0))   0).toFixed(2);
 

является чрезмерно сложным и может быть безопасно сведен к:

 var result = (Math.random() * 100).toFixed(2);
 

Однако не это .toFixed возвращает a String , а не a Number ! Это означает, что вы сравниваете числа со строками в своем if заявлении, что почти всегда дает ложные результаты (читай: не то, что вы ожидаете). Лучше отбросьте вызов .toFixed и сравните Number s с Number s. Это снова упростит строку:

 var result = Math.random() * 100;
 

Пересчет result

С каждой итерацией result переменной воссоздается / присваивается новое значение. Я ожидаю, что вы захотите вычислить его только один раз, а не для каждого элемента Reward . Если я прав, переместите строку над for циклом.