打乱数组——shuffle

阅读: 评论:0

打乱数组——shuffle

打乱数组——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});

转载于:.html

本文发布于:2024-01-31 04:27:16,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170664643725467.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数组   shuffle
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23