• 打乱数组——shuffle


    在学习vue移动端音乐项目时,看到一个打乱数组函数,感觉很有意思就记录一下(意外发现:slice是个有趣的知识点)

    原理:遍历数组,(let i = 0; i < _arr.length; i++),从0-i之间随机取一个数,与当前的arr[i]作交换,这样就把数组洗的很乱

    // 返回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本身???

    我们在打乱数组后,一定希望的是返回一个新的打乱过的数组,原来的数组不发生变化

    因为数组是引用类型,所以不能直接操作原数组(arr)。我们需要拷贝一份,将拷贝的数组(_arr)打乱之后return出去。
    那么问题来了,slice能做到操作拷贝后的数组(_arr)而不改变原数组(arr)吗?
    答案是:能做到一半

    因为let _arr = arr.slice()能将原数组(arr)的第一层深拷贝

    举个栗子:

    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也只会深拷贝对象(数组)的第一层。

    附加一个更骚的打乱方式:

    var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
    var numbers_ = numbers.slice();
    numbers_ = numbers_.sort(function(){ return Math.random() - 0.5});
    
  • 相关阅读:
    技术一定要动手做一遍才算自已的
    终于提离职了,感觉如释重负
    自我评定与学习计划
    MYSQL---INSERT...SELECT...
    MYSQL---LIMIT
    SQL---having
    MYSQL---数据定义
    CSS---Block和inline元素对比
    CSS---清除浮动
    T-SQL---分页语句
  • 原文地址:https://www.cnblogs.com/chenwenhao/p/10424068.html
Copyright © 2020-2023  润新知