2012-01-23 14 views
5

Estoy creando una lista de reproducción de canciones en javascript. He utilizado una matriz asociativa foo - la estructura de mi objeto se ve similar a:Obtener elemento aleatorio de matriz asociativa en javascript?

foo[songID] = songURL; 

Estoy tratando de construir en barajar funcionalidad. Me gustaría seleccionar una canción al azar de esta lista. ¿Hay una manera simple de hacer esto? La matriz no está indexada.

Respuesta

0

Usted podría intentar algo como esto:

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

Tenga en cuenta que esto es sólo una manera hacky de bordeando el hecho de que esto probablemente debería estar en una matriz con una estructura como esta:

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

Puede usar la función Object.keys(object) para obtener una matriz de las teclas de un objeto. Se puede encontrar una documentación muy buena para esta función en MDN.

También parece que tiene dos preguntas diferentes pero relacionadas.

Su tema pregunta cómo obtener un elemento aleatorio de un objeto. Para eso,

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

Pero también preguntas en el cuerpo de tu pregunta cómo barajar la matriz. Para eso, querrás una función de shuffle de algún tipo (muy probablemente una implementación de Fischer-Yates), y hazlo directamente.

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

Vale la pena mencionar que esto no funcionará en IE <8. –

+0

@kennis - eso se debe IE <9. – RobG

+0

Hmm, mirando hacia atrás en esto, leí mal la pregunta. Estaba preguntando cómo barajar, y di una función para elegir una canción al azar ... ¡Ups! Lo principal a tener en cuenta es que una vez que tienes una matriz con Object.keys, puedes mezclarla. – 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)]; 

usted debe utilizar un objeto para esto. Luego use una matriz indexada de objetos para la aleatorización, pero esto debería responder a su pregunta.

+0

Error trivial: siempre dará la primera clave porque durante la primera iteración, i === 0 y 1/++ siempre seré mayor que Math.random(). – Havvy

+1

No trivialmente, está calculando un número aleatorio diferente para cada clave. Incluso si Math.random() fuera perfectamente aleatorio, su función no puede dar un resultado verdaderamente aleatorio. La probabilidad del elemento 'N'th sería' (N/length) * Product ([1, N), N/Length) ', no N/Length. – Havvy

0

un método ineficiente es:

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

Como han dicho otros, almacenar mucho más eficiente la matriz nombre de propiedad y reutilizarlo que hacerla cada vez.

2

Esta es la función que hice para reproducir una canción de fondo aleatoria a partir de un hash de elementos de 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

Esto parece sospechosamente como mi respuesta integrada en una función que agrega un montón de código ruidoso no relacionado con la pregunta. Tus líneas cuarta y quinta son idénticas a las mías, excepto que reemplazaste 'return' con' self.currentBGM = ', aunque no haya' self' o 'currentBGM' en la pregunta. – Havvy

Cuestiones relacionadas