@Gigabait

Как сделать выборку по шансу?

Имеется массив значений. Получается если выпадает значение меньше 30 и после прибавления 30 вывод будет "Gold." Но что если должно быть "Bronze". Получается все отталкивается от того в какой последовательности расположены элементы в массиве. Но если подумать логически разве не шанс не должен быть 50 на 50 между Бронзой и Золотом , а сильвер падать чаще. Но в моём тесте (Из 10000) на оборот из-за того что золото на первом месте в массиве, оно падает чаще чем бронза.
В итоге меня проблема в том что я не знаю как правильно выбрать элемент по шансу. В моём примере выбор происходит по шансу И по положению в массиве.
Есть простая функция с выборкой по весу.
var data = [    {name: 'Gold', weight: 30},    {name: 'Silver', weight: 40},    {name: 'Bronze', weight: 30} ];
function GetRandFromArray2(data) {
	let total_sum = 0;
	for (let i = 0; i < data.length; ++i) {
	    total_sum += data[i].weight;
	}

	const rand = Math.floor(Math.random() * total_sum);

	total_sum = 0;
	for (let i = 0; i < data.length; ++i) {
	    total_sum += data[i].weight;
	    if (total_sum >= rand) {
	    	console.log(total_sum, rand)
	        return [ data[i].weight, data[i].name ];
	    }
	}	
}
  • Вопрос задан
  • 96 просмотров
Пригласить эксперта
Ответы на вопрос 2
0xD34F
@0xD34F Куратор тега JavaScript
if (total_sum >= rand) {

Равенство лишнее, верхняя граница не должна учитываться. Из-за этого у вас перекос в результатах.

Ну и конечно можно всё это записать гораздо короче:

function getRandom(arr, key) {
  const rand = Math.random() * arr.reduce((acc, n) => acc + n[key], 0) | 0;
  let sum = 0;
  return arr.find(n => (sum += n[key]) > rand);
}


const obj = getRandom(data, 'weight');
Ответ написан
@bqio
https://github.com/bqio
1. Заполняете массив размером 100.
2. Получаете рандомное значение из массива.

Например, заполняете массив до 10 значением 2, с 10 по 40 значением 1, с 40 по 100 значением 0.
Здесь получить значение 2 - 10%, значение 1 - 30%, значение 0 - 60%.
2 - Gold
1 - Silver
0 - Bronze
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Artezio Нижний Новгород
от 130 000 до 180 000 ₽
Artezio Москва
от 160 000 до 220 000 ₽
Intspirit Краснодар
от 80 000 до 150 000 ₽
21 янв. 2021, в 14:45
3000 руб./за проект
21 янв. 2021, в 14:41
8000 руб./за проект