听说你还不会JavaScript数组的用法
【摘要】 系列
用JS随机打乱数组
直接上代码
请多看注释哈
function shuffle(arr) { // 随机打乱数组
let _arr = arr.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
}
function getRandomInt(min, max) { // 获取min到max的一个随机数,包含min和max本身
return Math.floor(Math.random() * (max - min + 1) + min)
}
<template>
<div>
原数组:{{arr}}
<button @click="clickBut">click me!打乱数组</button></br></br>
打乱结果:{{result}}
</div>
</template>
<script>
export default {
data(){
return {
arr: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
result: []
}
},
methods:{
clickBut(){
this.result = this.shuffle(this.arr)
},
shuffle(arr) { // 随机打乱数组
let _arr = arr.slice() // 调用数组副本,不改变原数组
for (let i = 0; i < _arr.length; i++) {
let j = this.getRandomInt(0, i)
let t = _arr[i]
_arr[i] = _arr[j]
_arr[j] = t
}
return _arr
},
getRandomInt(min, max) { // 获取min到max的一个随机数,包含min和max本身
return Math.floor(Math.random() * (max - min + 1) + min)
}
}
}
</script>
<html>
原数组:<span id="span1"></span>
<button id="btn">click me!打乱数组</button> </br></br>
打乱结果:<span id="span2"></span>
</html>
<script>
function getRandomInt(min, max) { // 获取min到max的一个随机数,包含min和max本身
return Math.floor(Math.random() * (max - min + 1) + min)
}
function shuffle(arr) { // 随机打乱数组
let _arr = arr.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
}
//使用
function $(el){
return document.querySelector(el)
}
let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const $span2 = $('#span2');
$('#span1').textContent = arr;
$('#btn').onclick = function () {
$span2.textContent = shuffle(arr);
}
</script>
再来比较下多种数组去重性能
搞个测试模板
// 创建一个 1 ~ 10w 的数组,Array.from为ES6语法
let arr1 = Array.from(new Array(1000000), (x, index) => {
return index
})
let arr2 = Array.from(new Array(500000), (x, index) => {
return index + index
})
let start = new Date().getTime()
console.log('开始数组去重')
// 数组去重
function distinct(a, b) {
let arr = a.concat(b);
// 去重方法
}
console.log('去重后的长度', distinct(arr1, arr2).length)
let end = new Date().getTime()
console.log('耗时', end - start + 'ms')
测试代码
// 创建一个 1 ~ 10w 的数组,Array.from为ES6语法
let arr1 = Array.from(new Array(1000000), (x, index) => {
return index
})
let arr2 = Array.from(new Array(500000), (x, index) => {
return index + index
})
let start = new Date().getTime()
console.log('开始数组去重')
// 数组去重
function distinct(a, b) {
let arr = a.concat(b);
// 方法1,耗时约11675ms,约11s
// return arr.filter((item, index) => {
// return arr.indexOf(item) === index
// })
// 方法2,耗时约22851ms,约22s,性能最差
// for (let i = 0, len = arr.length; i < len; i++) {
// for (let j = i + 1; j < len; j++) {
// if (arr[i] == arr[j]) {
// arr.splice(j, 1);
// // splice 会改变数组长度,所以要将数组长度 len 和下标 j 减一
// len--;
// j--;
// }
// }
// }
// return arr
//方法3,耗时约12789ms,约12s,和方法1相当
// let result = []
// for (let i of arr) {
// !result.includes(i) && result.push(i)
// }
// return result
//方法4,耗时约23ms,ES5标准中性能最高
// arr = arr.sort()
// let result = [arr[0]]
// for (let i = 1, len = arr.length; i < len; i++) {
// arr[i] !== arr[i - 1] && result.push(arr[i])
// }
// return result
// 方法5,ES6的Set数据结构,耗时约20ms,性能高,代码简洁
// return Array.from(new Set([...a, ...b]))
// 方法6,耗时约16ms,所有方法中 性能最高! (千万级数据量下效率比方法5高4倍,for...of 为ES6语法)
let result = []
let obj = {}
for (let i of arr) {
if (!obj[i]) {
result.push(i)
obj[i] = 1
}
}
return result
}
console.log('去重后的长度', distinct(arr1, arr2).length)
let end = new Date().getTime()
console.log('耗时', end - start + 'ms')
结论
ES5标准中性能最高的数组去重方法为:
// 耗时约23ms
arr = arr.sort()
let result = [arr[0]]
for (let i = 1, len = arr.length; i < len; i++) {
arr[i] !== arr[i - 1] && result.push(arr[i])
}
return result
ES6标准中性能最高的数组去重方法为:
// 耗时约16ms (千万级数据量下效率比使用Set数据结构方法高4倍,for...of 为ES6语法)
let result = []
let obj = {}
for (let i of arr) {
if (!obj[i]) {
result.push(i)
obj[i] = 1
}
}
return result
代码既简洁性能又相对高的去重方法为:
// 耗时约20ms,性能高,代码简洁
return Array.from(new Set([...a, ...b]))
把一维数组按指定长度转为二维数组
将一维数组按指定长度转为二维数组
function pages(arr, len) {
const pages = []
arr.forEach((item, index) => {
const page = Math.floor(index / len)
if (!pages[page]) {
pages[page] = []
}
pages[page].push(item)
})
return pages
}
// 使用
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(pages(arr, 3)) // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
console.log(pages(arr, 8)) // [[1, 2, 3, 4, 5, 6, 7, 8], [9]]
应用场景是啥
如图,按需求,图标模块中的图标个数是不确定的,每页最多显示8个,超出8个的显示到第二页,实现向左滑动翻页。提供的数据是一个一维数组,这时就可以使用上面的代码按长度为8转为二维数组,再分页渲染到页面。
<template>
<swiper>
<swiper-slide v-for="(page, index) of pages" :key="index">
<div class="icon" v-for="item of page" :key="item.id">
<div class="icon-img">
<img :src="item.imgUrl">
</div>
<p>{{item.desc}}</p>
</div>
</swiper-slide>
</swiper>
<template>
<script>
...
data () {
return {
iconList: [] // 图标数据
}
},
computed: {
pages () {
const pages = []
this.iconList.forEach((item, index) => {
const page = Math.floor(index / 8)
if (!pages[page]) {
pages[page] = []
}
pages[page].push(item)
})
return pages
}
}
</script>
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)