Ważona generacja liczb losowych w JavaScript

Mam tablicę, która wygląda mniej więcej tak:

[
    {
        plays: 0,
        otherData: someValues
    }, {
        plays: 4,
        otherData: someValues
    }, {
        plays: 1,
        otherData: someValues
    }, {
        plays: 2,
        otherData: someValues
    } {
        plays: 9,
        otherData: someValues
    }, {
        plays: 7,
        otherData: someValues
    }, {
        plays: 5,
        otherData: someValues
    }, {
        plays: 0,
        otherData: someValues
    }, {
        plays: 8,
        otherData: someValues
    }
]

To zestaw informacji o utworach na liście odtwarzania, gdzieplays to ile razy została odtworzona piosenka. Próbuję wymyślić generator ważonych liczb losowych, który wybierze indeks elementu, ważony tak, że mniej odtwarzane utwory będą częściej wybierane. Oto kod, który mam teraz:

function pickRandom(){
    var oldIndex = index;
    if(songs.length <= 1)
        return index = 0;
    var unheard = [];
    for(i in songs){
        if(!songs[i].plays)
            unheard.push(i);
    }if(unheard.length > 0)
        return index = unheard[Math.round(Math.random() * (unheard.length - 1))];
    var tries = 0;
    while(index == oldIndex && tries < 100){
        index = Math.round(Math.random() * (songs.length - 1));
        tries++;
    }return index;
}

Z tym rozwiązaniem jest wiele rzeczy, z których nie jestem zadowolony. Po pierwsze, nie jest ważony tak bardzo, jak po prostu wybiera nieodtworzoną piosenkę lub dowolną starą, jeśli wszystko w tablicy zostało zagrane przynajmniej raz. Po drugie, tworzy nową tablicę, a ponieważ playlisty czasami mają setki piosenek, to jest to coś, od czego chciałbym się kierować, jeśli to możliwe.

Najbliższym rozwiązaniem, jakie udało mi się wymyślić, jest wielokrotne kopiowanie każdego elementu do nowej tablicy w oparciu o jegoplays wartość, a następnie wybierz element z tego, ale pogarsza to problem tworzenia nowej tablicy, ponieważ ta druga tablica może łatwo dotrzeć do tysięcy elementów. Byłbym bardzo wdzięczny za wszelką pomoc lub sugestie; nawet pseudokod byłby w porządku.

questionAnswers(2)

yourAnswerToTheQuestion