数组相关代码实现
洗牌算法-数组真正的变成乱序
思路:三种实现方式 原地和非原地和利用sort
function shuffle(){
let arr = [1,2,3,4,5,6,7,8,9]
console.log('原数组的顺序为:',arr)
// 原理: 依次遍历数组中的元素,将当前元素和之后的所有元素中随机拿出一个进行交换
// 原地: 不需要引入另外一个数组节约内存
const shf = (arr)=> {
for(let i = 0;i<arr.length;i++){
let curIndex = i+ Math.floor(Math.random()*(arr.length-i));
[arr[i],arr[curIndex]] = [arr[curIndex],arr[i]]
}
return arr
}
console.log('原地乱序的结果为:',shf(arr))
const shf1 = (arr)=> {
let _arr = []
while(arr.length){
let curIndex = Math.floor(Math.random()*arr.length)
// 这句和下面的两句效果一样,使用splice删除返回的是一个删除个数的数组
// _arr.push(arr.splice(curIndex,1)[0])
_arr.push(arr[curIndex])
arr.splice(curIndex,1)
}
return _arr
}
console.log('非原地乱序结果为', shf1(arr))
const shf2 = (arr) => {
//sort每次会拿两个值然后通过参数进行排序
arr.sort(function () {
return 0.5 - Math.random() })
return arr
}
console.log('非原地乱序结果为', shf2(arr))
}
shuffle()
附加小知识1:
Math.random() 生成[0,1)之间的一个随机数
Math.random()*4 生成[0,4)之间的一个随机数
Math.random()4+1 生成[1,5)之间的一个随机数
Math.floor(Math.random()(max+1)) 生成[0,max]之间的一个随机数
Math.floor()向下取整
Math.ceil()向上取整
Math.round()四舍五入
伪类数组arguments转为数组
思路:
// arguments 伪类数组转为数组
function trans(arr, len) {
console.log(arr, len)
console.log(arguments)
// 方法一 :利用es6的Array.from()和扩展运算符
//Array.from() : 将类对象转为数组;将可遍历对象转为数组
let arr1 = Array.from(arguments)
let arr2 = [...arguments]
// 方法二:利用apply展开,和数组连接完之后,修改this的指向,指向数组
let arr3 = [].concat.call(...arguments)
let arr4 = [].concat.apply([], arguments)
// 方法三:利用iterator接口遍历
let arr5 = []
for (let item of arguments) {
arr5.push(item)
}
console.log('arr', arr1, arr2, arr3, arr4, arr5)
}
const arr = [1, 2, 3]
trans(arr, arr.length)
附加小知识1:
伪数组:是类似于数组的对象,按照索引存储数据且具有length属性,因为不是数组,所以不具有数组的push,forEach等方法
argument是伪数组,它代表是函数的实参
let divEle = document.querySelectorAll(‘div’) 这个也是一个伪数组
附加小知识2:
call,apply,bind修改this指向
call:参数列表 fn.call(obj,args1,args2…)
apply:参数数组 fn.apply(obj,[args])
bind: 参数列表
bind会创建一个新的函数,再调用这个新的函数(这个时候this进行了重新绑定),多次bind只认第一次bind值,且bind中this不能通过apply,call修改
数组扁平化
思路:
利用数组的迭代方法:reduce,map,some
利用es6的flat方法
利用序列化后正则
function flat() {
let arr = [1, 2, [3, 4, [5, 6, 7, [8, 9]]]]
console.log('origin arr:', arr)
const flat1 = arr => {
return arr.reduce((pre, cur) => {
return pre.concat(Array.isArray(cur) ? flat1(cur) : cur)
}, [])
}
console.log('flat1 arr', flat1(arr))
let res = []
const flat2 = arr => {
arr.map(item => {
Array.isArray(item) ? flat2(item) : res.push(item)
})
}
flat2(arr)
console.log('flat2 arr', res)
const flat3 = arr => {
// arr中元素只要有一个是数组就返回true
while (arr.some(item => Array.isArray(item))) {
// 将arr运用扩展运算符 进行依次扩展 直到arr中元素没有数组
arr = [].concat(...arr)
}
return arr
}
console.log('flat3 arr', flat3(arr))
// Infinite表示不管有多少层,都会拉成一维数组
console.log('flat4 arr', arr.flat(Infinity))
console.log('flat5 arr', JSON.parse(`[${
JSON.stringify(arr).replace(/(\[|\])/g, '')}]`))
}
flat()
数组去重
思路:
利用set集合去重
利用reduce,filter
利用map
function unique() {
let arr = [1, 1, 2, 3, undefined, undefined, null, null]
console.log('origin arr', arr)
console.log('unique1 arr', [...new Set(arr)])
console.log('unique1 arr', Array.from(new Set(arr)))
console.log('unique2 arr ', arr.reduce((pre, cur) => {
return pre.includes(cur) ? pre : [...pre, cur]
}, []))
console.log('unique3 arr', arr.filter((item, index) => arr.indexOf(item) == index ? true : false))
const unique3 = arr => {
let map = new Map()
arr.map(item => {
map.set(item + (typeof item), item)
})
return Array.from(map.values())
}
console.log('unique3 arr', unique3(arr))
}
unique()
合并数组
思路:可以采用concat连接生成新的数组方式,也可以采用遍历的方式,遍历的方式可以考虑哪个数组小操作哪个,也可以利用apply的特性
function mergeArray() {
let arr1 = [1, 2, 3], arr2 = [3, 4, 50]
console.log