打亂數組——shuffle

在學習vue移動端音樂項目時,看到一個打亂數組函數,感受頗有意思就記錄一下(意外發現:slice是個有趣的知識點)vue

原理:遍歷數組,(let i = 0; i < _arr.length; i++),從0-i之間隨機取一個數,與當前的arr[i]做交換,這樣就把數組洗的很亂es6

// 返回min和max之間的一個隨機數,包括min和max
function getRandomInt(min, max) { 
  return Math.floor(Math.random() * (max - min + 1) + min) // +1是保證能夠取到上限值
}

// 洗牌函數
function shuffle(arr) {  
  let _arr = arr.slice()   // 下面會講到slice的特別之處
  for (let i = 0; i < _arr.length; i++) {
    let j = getRandomInt(0, i)
    let t = _arr[i]
    _arr[i] = _arr[j]
    _arr[j] = t
  }
  return _arr
}
var arr = [0,1,2,3,4];
shuffle(arr);

打亂數組就是這麼簡單,下面讓咱們說說爲何要用slice處理一下,而不是直接用arr自己???數組

咱們在打亂數組後,必定但願的是返回一個新的打亂過的數組,原來的數組不發生變化dom

由於數組是引用類型,因此不能直接操做原數組(arr)。咱們須要拷貝一份,將拷貝的數組(_arr)打亂以後return出去。
那麼問題來了,slice能作到操做拷貝後的數組(_arr)而不改變原數組(arr)嗎?
答案是:能作到一半函數

由於let _arr = arr.slice()能將原數組(arr)的第一層深拷貝學習

舉個栗子:code

let obj = [
    {
        name:0,
        job:0
    },
    {
        name:1,
        job:1
    },
    {
        name:2,
        job:2
    }
];
let copy = obj.slice(0);  // 0可省略
copy[1].name = 10;  // 改變第二層,對象的屬性name
console.log(obj[1].name); // 10
console.log(copy[1].name); // 10
copy[2] = {name: 20,job: 20};  // 改變第一層,將整個對象替換成別的對象(改變copy[2]對象的內存指向)
console.log(obj[2].name); // 2
console.log(copy[2].name); // 20

綜上,就很好理解爲何要用let _arr = arr.slice()處理了。對象

注:es6的Object.assign解構賦值;Array的concat、map、filter也只會深拷貝對象(數組)的第一層。內存

附加一個更騷的打亂方式:get

var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
var numbers_ = numbers.slice();
numbers_ = numbers_.sort(function(){ return Math.random() - 0.5});
相關文章
相關標籤/搜索