2012-01-23 17 views
5

Sto costruendo una playlist di brani in javascript. Ho usato un array associativo foo - la struttura del mio oggetto appare simile a:Ottieni elementi casuali dall'array associativo in javascript?

foo[songID] = songURL; 

Sto cercando di costruire in mischiare funzionalità. Vorrei selezionare una canzone a caso da questa lista. C'è un modo semplice per farlo: l'array non è indicizzato.

risposta

0

Si potrebbe provare qualcosa di simile:

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

Si noti che questo è davvero solo un modo hacky di battiscopa intorno al fatto che questa roba dovrebbe probabilmente essere in un array con una struttura come questa:

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

È possibile utilizzare la funzione Object.keys(object) per ottenere una matrice delle chiavi di un oggetto. Una documentazione molto buona per questa funzione è disponibile su MDN.

Sembra che tu abbia due domande diverse ma correlate.

L'argomento chiede come ottenere un elemento casuale da un oggetto. Per quello,

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

Ma si chiede anche nel corpo della domanda come rimescolare l'array. Per questo, ti consigliamo una funzione di tipo shuffle (molto probabilmente un'implementazione di Fischer-Yates), e farlo direttamente.

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

Vale la pena ricordare che questo non funzionerà in IE <8. –

+0

@kennis - che dovrebbero essere IE <9. – RobG

+0

Hmm, guardando indietro su questo, ho letto male la domanda. Stava chiedendo come mescolare, e ho dato una funzione per scegliere una canzone a caso ... whoops. La cosa principale da notare è che una volta che si dispone di un array con Object.keys, è possibile mischiarlo. – 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)]; 

è necessario utilizzare un oggetto per questo. Quindi usa una matrice indicizzata di oggetti per la randomizzazione, ma questo dovrebbe rispondere alla tua domanda.

+0

Bug banale: questo darà sempre la prima chiave perché durante la prima iterazione, i === 0, e 1/++ i sarà sempre maggiore di Math.random(). – Havvy

+1

Non banali, stai calcolando un numero casuale diverso per ogni chiave. Anche se Math.random() era perfettamente casuale, la tua funzione non può dare un risultato veramente casuale. La probabilità per l'elemento 'N'th sarebbe' (N/lunghezza) * Prodotto ([1, N), N/Lunghezza) ', non N/Lunghezza. – Havvy

0

Un metodo inefficiente è:

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

Come altri hanno già detto, magazzini molto più efficiente l'array nome di proprietà e riutilizzarlo che fare ogni volta.

2

Questa è la funzione che ho eseguito per riprodurre una canzone di sottofondo casuale da un hash di elementi audio.

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

Sembra sospettosamente come se la mia risposta fosse inserita in una funzione che aggiunge un sacco di codice rumoroso non correlato alla domanda. La tua quarta e quinta riga sono identiche alle mie, tranne che hai sostituito 'return' con' self.currentBGM = ', anche se non ci sono' self' o 'currentBGM' nella domanda che viene posta. – Havvy

Problemi correlati