2012-01-23 91 views
5

Tôi đang xây dựng danh sách phát các bài hát bằng javascript. Tôi đã sử dụng một mảng kết hợp foo - cấu trúc của đối tượng của tôi trông giống như:Lấy phần tử ngẫu nhiên từ mảng kết hợp trong javascript?

foo[songID] = songURL; 

Tôi đang cố gắng xây dựng trong xáo trộn chức năng. Tôi muốn chọn một bài hát ngẫu nhiên từ danh sách này. Có một cách đơn giản để làm điều này - mảng không được lập chỉ mục.

Trả lời

0

Bạn có thể thử một cái gì đó như thế này:

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

Lưu ý rằng điều này thực sự chỉ là một cách hacky của viền xung quanh thực tế là công cụ này có lẽ nên được trong một mảng với một cấu trúc như thế này:

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

Bạn có thể sử dụng hàm Object.keys(object) để lấy một mảng các khóa của đối tượng. Tài liệu rất tốt cho chức năng này có thể được tìm thấy tại MDN.

Bạn cũng có vẻ có hai câu hỏi khác nhau nhưng có liên quan.

Chủ đề của bạn hỏi cách lấy một phần tử ngẫu nhiên từ một đối tượng. Đối với điều đó,

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

Nhưng bạn cũng hỏi trong phần câu hỏi của bạn cách trộn mảng. Đối với điều đó, bạn sẽ muốn có một hàm shuffle của một số loại (hầu hết có thể là việc triển khai Fischer-Yates) và thực hiện điều đó trực tiếp.

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

Nó đáng nói rằng điều này sẽ không làm việc trong IE <8. –

+0

@kennis - Đó nên là IE <9. – RobG

+0

Hmm, nhìn lại về vấn đề này, tôi không nhận định câu hỏi. Nó đã hỏi làm thế nào để trộn, và tôi đã đưa ra một chức năng để chọn một bài hát ngẫu nhiên ... rất tiếc. Điều quan trọng cần lưu ý là một khi bạn có một mảng với Object.keys, bạn có thể trộn nó. – 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)]; 

Bạn nên sử dụng một đối tượng cho việc này. Sau đó, sử dụng một mảng các đối tượng được lập chỉ mục để phân ngẫu nhiên, nhưng điều này sẽ trả lời câu hỏi của bạn.

+0

Lỗi nhỏ: Điều này sẽ luôn cung cấp khóa đầu tiên bởi vì trong lần lặp đầu tiên, i === 0 và 1/++ tôi sẽ luôn lớn hơn Math.random(). – Havvy

+1

Không đặc biệt, bạn đang tính toán một số ngẫu nhiên khác nhau cho mỗi khóa. Ngay cả khi Math.random() hoàn toàn ngẫu nhiên, hàm của bạn không thể đưa ra kết quả thật sự ngẫu nhiên. Xác suất cho phần tử 'N'th sẽ là' (N/chiều dài) * Sản phẩm ([1, N), N/Độ dài) ', không phải là N/Độ dài. – Havvy

0

Một phương pháp hiệu quả là:

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

Như những người khác đã nói, lưu trữ nhiều hiệu quả hơn mảng tên thuộc tính và tái sử dụng nó hơn để làm cho nó mỗi lần.

2

Đây là chức năng tôi đã tạo để phát một bài hát nền ngẫu nhiên từ phần băm của các phần tử âm thanh.

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

Điều này có vẻ nghi ngờ giống như câu trả lời của tôi được nêu trong một hàm bổ sung thêm rất nhiều mã ồn ào không liên quan đến câu hỏi. Dòng thứ tư và thứ năm của bạn giống với của tôi, ngoại trừ bạn đã thay thế 'return' bằng' self.currentBGM = ', mặc dù không có' self' hoặc 'currentBGM' trong câu hỏi đang được hỏi. – Havvy

Các vấn đề liên quan