私は次のような配列を持っています:
[
{
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
}
]
これは、プレイリスト内の曲に関する一連の情報であり、は曲plays
が再生された回数です。私は、要素のインデックスを選択する加重乱数ジェネレーターを考え出そうとしています。これは、再生されていない曲が選択される可能性が高くなるように加重されています。これが私が今持っているコードです:
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;
}
このソリューションには、私が不満に思っていることがたくさんあります。まず、実際には未再生の曲、または配列内のすべてが少なくとも1回再生されている場合は古いランダムな曲を選択するだけなので、それほど重み付けされていません。第二に、それは新しい配列を作成します、そしてプレイリストは時々何百もの曲を持っているので、それは私が可能であれば避けたいものです。
私が思いついた最も近い解決策は、各要素をそのplays
値に基づいて新しい配列に複数回コピーし、その中から要素を選択することですが、その2番目の配列以降、新しい配列を作成する問題が悪化します何千もの要素に簡単に到達できます。私はどんな助けや提案にも大いに感謝するでしょう。擬似コードでも問題ありません。