2012-01-23 3 views
5

Я создаю плейлист с песнями в javascript. Я использовал ассоциативный массив foo - структура моего объекта выглядит сродни:Получить случайный элемент из ассоциативного массива в javascript?

foo[songID] = songURL; 

Я пытаюсь построить в перетасовках функциональности. Я хотел бы выбрать песню в случайном порядке из этого списка. Есть ли простой способ сделать это - массив не индексируется.

ответ

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); 

Заметьте, что это на самом деле просто Hacky способ обходя тем, что этот материал должен вероятно быть в массиве со структурой, как это:

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

Вы можете использовать функцию 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

Стоит отметить, что это не будет работать в IE <8. –

+0

@kennis - Это должно быть IE <9. – RobG

+0

Хм, оглядываясь назад на это, я неправильно понял вопрос. Он спрашивал, как перетасовать, и я дал функцию для выбора случайной песни ... кричит. Главное отметить, что как только у вас есть массив с Object.keys, вы можете перетасовать его. – Havvy

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)]; 

Вы должны использовать объект для этого. Затем используйте индексированный массив объектов для рандомизации, но это должно ответить на ваш вопрос.

+0

Trivial bug: Это всегда даст первый ключ, потому что во время первой итерации i === 0 и 1/++ i всегда будет больше, чем Math.random(). – Havvy

+1

Нетривиально, вы вычисляете различное случайное число для каждого ключа. Даже если Math.random() был совершенно случайным, ваша функция не может дать действительно случайный результат. Вероятность для элемента 'N'th будет' (N/length) * Product ([1, N), N/Length) ', а не N/Length. – Havvy

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; 
} 

Как уже говорил другим, гораздо более эффективно хранить массив имени свойства и повторно использовать его, чем сделать это каждый раз.

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(); 
} 
+0

Это выглядит подозрительно, как мой ответ, вложенный в функцию, которая добавляет много шума, не связанного с вопросом. Ваша четвертая и пятая строки идентичны моей, за исключением того, что вы заменили 'return' на' self.currentBGM = ', даже если в заданном вопросе нет' self' или 'currentBGM'. – Havvy

Смежные вопросы