Показать сообщение отдельно
  #6 (permalink)  
Старый 14.12.2020, 17:20
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,012

Сообщение от LimonDK
Была идея просто создать список, в который поместить 'a' 10 раз, 'b' 20 раз и т.д.
кажется, понял.
потом из этого списка равновероятно выбираем элемент, и он оказывается одним из символов.
это как-раз то, что рони сделал. В общем виде примерно так:

function rnd(map) {
    const keys = Object.keys(map);
    if (!keys.length) {
        return undefined;
    }
    const sum = keys.reduce((s, key) => s + map[key], 0);
    const r = Math.random() * sum;
    let acc = 0;
    for (let i = 0; i < keys.length; ++i) {
        acc += map[keys[i]];
        if (acc > r) {
            return keys[i];
        }
    }
    return keys[keys.length - 1];
}

// для проверки рандомности
function getStat(map, iters) {
    const stat = Object.create(null);
    Object.keys(map).forEach(key => { stat[key] = 0; });
    for (let i = 0; i < iters; ++i) {
        const v = rnd(map);
        stat[v]++;
    }
    Object.keys(map).forEach(key => { stat[key] = stat[key] / iters; });
    return stat;
}

alert(JSON.stringify(getStat({'a': 10,'b': 20,'c': 30}, 40000), '', 4));
Ответить с цитированием