我有一个看起来像这样的数组:
[
{
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;
}
这个解决方案有很多我不满意的地方。首先,它的权重并没有太大,因为它实际上只是选择一首未播放的歌曲,或者如果数组中的所有内容都至少播放过一次,则可以选择任何旧的随机歌曲。其次,它创建了一个新数组,并且由于播放列表有时会包含数百首歌曲,因此如果可能的话,我想避免这种情况。
我能想出的最接近的解决方案是根据每个元素的值将每个元素多次复制到一个新数组中plays
,然后从中挑选一个元素,但这会加剧创建新数组的问题,因为第二个数组可以轻松达到数千个元素。我会非常感谢任何帮助或建议;即使是伪代码也可以。