从javascript中的关联数组中获取随机元素?

时间:2012-01-23 03:39:35

标签: javascript

我正在用javascript构建歌曲播放列表。我使用了一个关联数组foo - 我的对象的结构看起来类似于:

foo[songID] = songURL;

我正在尝试构建改组功能。我想从这个列表中随机选择一首歌。有没有一种简单的方法 - 数组没有索引。

5 个答案:

答案 0 :(得分:9)

您可以使用函数Object.keys(object)来获取对象键的数组。可以在MDN找到关于此功能的非常好的文档。

您似乎也有两个不同但相关的问题。

您的主题询问如何从对象中获取随机元素。为此,

var randomProperty = function (object) {
  var keys = Object.keys(object);
  return object[keys[Math.floor(keys.length * Math.random())]];
};

但你也在问题正文中询问如何改组阵列。为此,你需要某种shuffle函数(很可能是Fischer-Yates的一个实现),并直接这样做。

var objectKeysShuffled = function (object) {
    return shuffle(Object.keys(object));
};

答案 1 :(得分:2)

这是我从音频元素的散列中播放随机背景歌曲的功能。

this.bgm = {} //I later added audio elements to this
this.playRandomBGM = function()
{
    var keys = Object.keys(this.bgm);
    self.currentBGM = keys[Math.floor(keys.length * Math.random())];
    console.log("Playing random BGM: " + self.currentBGM);
    self.bgm[self.currentBGM].play();
}

答案 2 :(得分:0)

您可以尝试这样的事情:

var obj = {
    'song1': 'http://...1',
    'song2': 'http://...2',
    'song3': 'http://...3',
    'song4': 'http://...4',
    'song5': 'http://...5',
    'song6': 'http://...6',
}, tempArr = [], len, rand, song;

for ( var key in obj )
    if ( obj.hasOwnProperty(key) )
        tempArr.push( obj[key] );

len = tempArr.length;
rand = Math.floor( Math.random() * len );
song = tempArr[rand];
document.write(song);

请注意,这实际上只是一种愚蠢的方式来绕过这样的事实:这个东西应该是一个具有这样结构的数组:

var songs = [
    {title: 'Song1', url: 'http://...1.mp3'},
    {title: 'Song2', url: 'http://...2.mp3'},
    {title: 'Song3', url: 'http://...3.mp3'}
];

答案 3 :(得分:0)

function fetchRandom(arr) {
    var ret,
        i = 0;
    for (var key in arr){
        if (Math.random() < 1/++i){
           ret = key;
        }
    }
    return ret;
}

var randomSong = foo[fetchRandom(foo)];

你应该使用一个对象。然后使用索引的对象数组进行随机化,但这应该回答你的问题。

答案 4 :(得分:0)

效率低下的方法是:

function randomProperty(obj) {
  var a = [];
  for (var p in obj) {
    if (obj.hasOwnProperty(p)) {
      a.push(p);
    }
  }
  return a.length? obj[ a[a.length * Math.random() | 0]] : void 0;
}

正如其他人所说的那样,更有效地存储属性名称数组并重新使用它,而不是每次都使用它。