通过总结数组方法,我形成了数组知识闭环

100 阅读4分钟

前言

在与同学交流的过程中发现自己对数组的很多方法都还处于半知半解的地步,于是下定决心通过数组方法建立起自己关于数组知识的闭环,希望通过这篇文章展示自己的思考方式,并将数组相关的一些零散的知识联系起来

常见方法

Array.isArray()

确定传递的值是否是Array

Array.from()

对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例

后面有两个延伸讲解类数组与深浅拷贝

延伸1 类数组(伪数组)

类数组是结构与数组非常相似的对象的,key为数字或数字的字符串形式,且含有length属性,不能使用数组的方法

模板

这里只是类似,便于理解,并不是类数组,因为类数组不会手动添加length,类数组会和访问数组一样的方式访问元素,而不是这里key严格的0,1,2

//key为数字或数字字符,且有length
let arr={0:"0","1":"1",2:2,length:3}
//可以通过数组的方式访问
console.log(arr[2]) //2

常见类数组

//arguments 传递给函数的参数的对象
function arg(a,b,c){
  console.log(arguments)
  console.log(arguments.length)
  console.log(Object.prototype.toString.call(arguments)) // Arguments
}
arg(1,2,3)

//部分获取DOM元素方法返回的对象,如
document.getElementsByClassName('类名')

类数组转换为数组的方法

1、slice()

let arr=Array.prototype.slice.call(arguments)

2、Array.from()

let arr=Array.from(arguments)

3、将类数组指向数组的原型对象

注意 这种方法在类数组是DOM元素返回对象时,可以转换为数组,但是不能进行数组操作

arr.__proto__ = Array.prototype

延伸2 浅拷贝与深拷贝

在掘金上发现一篇特别透彻的,可以前往查看 浅拷贝与深拷贝 - 掘金 (juejin.cn)

回归正传,继续讲解数组的方法

基础方法

一些特别基础的就不多加描述了,比如:

length、push()、pop()、shift()、unshift()、join()、sort()、reverse()

常用进阶方法

concat()

合并数组并返回一个新数组

使用场景

1、个人写快排的时候喜欢在递归时用concat(),然后在取对比值时就需要将对比值从原数组中截取下来,也就要用到splice(),用法移步下一个

//伪代码
quickSort(arr){
  if(arr.length===1)//终止
  let cur=arr.splice(0,1)[0]
  let left=[]
  let right=[]
  for(let k of arr){
    //小的放left,大于等于的放right
  }
  //左边的一定比cur小,右边的一定大于等于cur,合并成一个排好序的新数组返回
  return quickSort(left).concat([cur],quickSort(right)) 
}

2、用reduce()实现flat时会用到,详见下文

splice()

删除或替换现有元素,在某个位置增加新的元素来修改数组,注意 原数组会被修改

//如果删除数量为0就是在那个位置增加值
splice(操作位置,删除数量,值1,值2)

slice()

返回一个有start到end的新的数组对象,其实就是对数组在这个区间的一个浅拷贝

注意 不会改变原数组

slice()//返回一个原数组的浅拷贝
//如果参数为负数,就是从数组末尾往前数
slice(start)//从start到结束
slice(start,end)//从start到end

延伸 字符串中的slice()方法,及与substr()和substring()的区别?

fill()

填充数组从start到end的所有元素

//一般初始化数组常用
const arr=new Array(10).fill(0)
const arr=new Array(10).fill(false)

flat()

数组扁平化,指定深度遍历元素并返回遍历的新数组

特性

1、根据参数降维数组

2、参数<=0时不降维

3、参数为Infinity时,转为一维数组

4、没有参数时会跳过原数组中的空位

手写flat

思路 遍历数组中的元素并找到类型是数组的元素,然后将他展开

//实现flat的方法有很多,这里使用reduce()来实现,也算reduce()的一个使用场景,关于reduce(),可以移步下一个方法介绍
//这里只是最简单的转换,没有做更多特性处理
const myflat = arr =>{
    return arr.reduce((pre,cur)=>{
      //如果是数组,那就先将数组展开
      return pre.concat(Array.isArray(cur) ? myflat(cur) : cur);
    },[]);
};

reduce()

让数组中的元素按序执行你定义的有reduce的函数,每次运行时会将先前元素的计算结果为参数传入,最后将结果汇总为单个返回值返回 这里只是大概总结,想了解更多的可以自行查阅

参数

pre 上一步计算后的值,也是计算结束后的返回值

cur 当前元素

return的值一定要注意,因为会按序进行下一步递归

明白这三点就可以进行常规使用了

用法一

计算数组所有元素和

const arr = [1, 2, 3, 4, 5]
let sum = arr.reduce((pre, cur) => {
  pre += cur
  return pre
})

用法二

数组去重

//思路:pre为没有重复的数组,每当pre里没有cur时才把cur放入pre,最后返回pre
//注意在最开始需要给pre一个初始值,也就是空数组[]
const arr = [1, 2, 3, 4, 5]
let arr1 = arr.reduce((pre, cur) => {
  if(!pre.includes(cur)) pre.push(cur)
  return pre
},[])

用法三

实现flat,详情请看上面

forEach()

对数组元素执行一次给定的函数 就是增强for循环

用法

计算数组所有元素和

const arr = [1, 2, 3, 4, 5]
let sum = 0
arr.forEach(sumArr)
function sumArr(i){
  sum+=i
}

总结

这篇文章把数组的常用方法形成了一个环,在某些场景上用到的数组方法可以是有关联的, 找到他们的联系,然后理清自己的数组知识结构,就是本篇最大的收获了