首頁  >  文章  >  web前端  >  javascript實現數組內值索引隨機化及創建隨機數組的方法_javascript技巧

javascript實現數組內值索引隨機化及創建隨機數組的方法_javascript技巧

WBOY
WBOY原創
2016-05-16 15:46:151058瀏覽

本文實例講述了javascript實現數組內值索引隨機化及創建隨機數組的方法。分享給大家供大家參考。具體如下:

今天在QW交流群組裡看到有同學討論使數組隨機化的問題,其中給出的演算法很不錯,讓我想起了之前自己實現過的不怎麼「漂亮」的方法。想想我們有時在繁忙的寫業務代碼時只是為了實現其功能,並未花太大心思去思考是否有更好的實現方法。

就這個數組問題(隨即排序一個數組裡的值,返回一個新數組)來說,我以前的實現方法是這樣的:

function randArr(arr) {
 var ret = [],
 obj = {},
 i = arr.length,
 l = i,
 n;
 while (--i >= 0) {
  n = Math.floor( Math.random() * l );
  if (obj[n] === void 0) {
   ret[ret.length] = obj[n] = arr[n];
  } else {
   i++;
  }
 }
 return ret;
}

上面的程式碼會運作,但並不是一個好的演算法,它打算執行「原始數組的長度」次循環,每一次循環會隨機取一個原數組中的索引,然後判斷該索引是否已被取過,如果沒有則把該索引的值放入新數組中,如果取過則把自減鍵i 自增1(目的是重複該次循環直到取到另一個未取過的索引)。這樣的方法的性能是很看人品的,原因相信看到這種思路的同學都已明白了。

現在給出群組裡那位同學的演算法:

function randArr(arr) {
 var ret = [],
 i = arr.length,
 n;
 arr = arr.slice(0);
 while (--i >= 0) {
  n = Math.floor( Math.random() * i);
  ret[ret.length] = arr.splice(n, 1)[0];
 }
 return ret;
}

這是一個相當巧妙的演算法,在每次循環中取一個隨機的索引後,並把它的值從數組中刪除,這樣,如果後面依然隨機取到這個索引,這個索引就已經不再是上一次取到的值了,而且隨機數的值範圍會根據數組的長度的減小而減小,這樣就能一次性循環一定的次數而得到理想的結果。

也看到了一個改進版的,是考慮到了對數組的刪除操作而導致的些許性能問題,運用了JK大的洗牌算法,即把每一次刪除操作改為了位置替換操作(取到的這個索引的值和目前自減鍵i 對應的值進行互換),這樣對整個數組的影響是最小的,還是放代碼吧:

function randArr(arr) {
 var ret = [],
 i = arr.length,
 n;
 arr = arr.slice(0);
 
 while (--i >= 0) {
  n = Math.floor( Math.random() * i);
  ret[ret.length] = arr[n];
  arr[n] = arr[i];
 }
 return ret;
}

最後給一個「創建一個值為min~max間的隨機數組」的方法,演算法原理同上面的差不多:

function makeRandArr(min, max) {
 var ret = [],
 obj = {},
 n;
 for (; max >= min; max--) {
  n = Math.ceil( Math.random() * (max - min) ) + min;
  ret[ret.length] = obj[n] || n;
  obj[n] = obj[max] || max;
 }
 return ret;
}

希望本文所述對大家的javascript程式設計有所幫助。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn