Array那些事~~~

427 阅读2分钟

前言:看了很多文章都没有系统的总结一下Array常用的api,于是我产生了一个大胆的想法,总结了一些Array常用的api,以及面试中经常会被问到的数组相关的知识点。

开局一张图

Map Shot 1617009128796.png

部分api的实现方式

map

作用:对数组中每一项进行操作后返回新的数组

function map (array, callback) {
  const arr = []
  // 遍历当前数组每个元素, 调用callback得到一个结果数据, 添加arr
  for (let index = 0; index < array.length; index++) {
    const element = array[index];
    const result = callback(element, index, array)
    arr.push(result)
  }
  return arr
}

reduce

作用:对数组中每一项进行操作后返回回调函数中的第一个参数的值

ps: 功能很强大,数组中所有的api都可以通过它来实现

function reduce (array,callback, initValue) {
  // 结果为初始值
  let total = initValue
  // 遍历当前数组每个元素, 调用callback得到一个累加的结果数据
  for (let index = 0; index < array.length; index++) {
    const element = array[index];
    total = callback(total, element, index, array)
  }

  // 返回结果
  return total
}  

filter

作用:返回数组中满足条件的元素组成的新数组

function filter (array,callback) {
  const arr = []
  // 遍历当前数组每个元素, 调用callback得到一个布尔值, 如果为true, 将当前element添加到arr
  for (let index = 0; index < array.length; index++) {
    const element = array[index];
    const result = callback(element, index, array)
    if (result) {
      arr.push(element)
    }
  }
  return arr
}  

find

作用:返回数组中满足条件的第一个元素

function find (array,callback) {
  // 遍历当前数组每个元素, 调用callback得到一个布尔值, 如果为true, 返回当前元素
  for (let index = 0; index < array.length; index++) {
    const element = array[index];
    const result = callback(element, index)
    if (result) {
      return element
    }
  }
  return undefined
}  

findIndex

作用:返回数组中满足条件的第一个元素的下标

function findIndex (array,callback) {
  // 遍历当前数组每个元素, 调用callback得到一个布尔值, 如果为true, 返回当前元素的下标
  for (let index = 0; index < array.length; index++) {
    const element = array[index];
    const result = callback(element, index, array)
    if (result) {
      return index
    }
  }
  return -1
}

every

作用:判断数组中是否所有的元素都满足条件

function every (array,callback) {
  // 遍历当前数组每个元素, 调用callback得到一个布尔值, 一旦是false, 返回false
  for (let index = 0; index < array.length; index++) {
    const element = array[index];
    const result = callback(element, index, array)
    if (!result) {
      return false
    }
  }
  return true
}  

some

作用:判断数组中是否至少有一个元素满足条件

function some (array,callback) {
  // 遍历当前数组每个元素, 调用callback得到一个布尔值, 一旦是true, 返回true
  for (let index = 0; index < array.length; index++) {
    const element = array[index];
    const result = callback(element, index)
    if (result) {
      return true
    }
  }
  return false
}  

forEach

作用:遍历数组

function forEach(array, callback) {
  // 遍历当前数组每个元素, 调用callback
  for (let index = 0; index < array.length; index++) {
    callback(array[index], index, array);
  }
}

concat

作用:连接数组

function concat (array, ...values) {
  const arr = [...array]
  // 遍历values, 将value或者value中的元素添加arr中
  values.forEach(value => {
    if (Array.isArray(value)) {
      arr.push(...value)
    } else {
      arr.push(value)
    }
  })
  
  return arr
}

slice

作用:切割数组

ps:Array.prototype.slice.call()和Array.form()的作用一样,是浅拷贝一个数组

function slice(array, begin, end) {
  const arr = []

  // 如果原数组是空组件, 直接返回
  if (array.length===0) {
    return arr
  }
  // 处理没有指定
  begin = begin || 0
  end = end || array.length
  // 范围的限制
  if (begin<0) {
    begin = 0
  }
  if (end>array.length) {
    end = array.length
  }

  // 先实现主体操作
  for (let index = begin; index < end; index++) {
    arr.push(array[index])
  }

  return arr
}

数组去重

第一种:利用forEach+indexOf

function unique1(array){
    let arr = [];
    array.forEach(item=>{
        if(array.indexOf(item)===-1){
            arr.push(item)
        }
    })
    return arr;
}

第二种:利用forEach+对象容器

 function unique2(array){
     let arr = [];
     let tempObj = {};
     array.forEach(item=>{
         if(!tempObj.hasOwnProperty(item)){
             tempObj[item] = true;
             arr.push(item)
         }
     })
     return array
 }

第三种:利用Set+...运算符

function unique3(array){
    return [...new Set(array)]
}

找出一个数组中出现次数最多的元素

创建一个对象,把素组中的元素作为key,出现的次数作为value塞进这个对象,最后获取出对象的value,利用Math.max()方法找出最大值,最后再根据这个最大值去反查key值

 function findElement(array){
       let tempObj = {};
       array.forEach(item=>{
           tempObj[item] = tempObj[item]?++tempObj[item]:1;
       })
       let maxNumber = Math.max(...Object.values(tempObj));
       let maxValueArray = [];
       Object.keys(tempObj).forEach(item=>{
           if(tempObj[item]===maxNumber){
               maxValueArray.push(Number(item))
           }
       })
       return maxValueArray;
 }

用数组实现一个栈结构

先进后出

function Stack() {

  // 用于保存元素数据的数组
  let arr = []
  
  // 进栈 push
  this.push = function (element) {
    arr.push(element)
  }

  // 出栈: pop()
  this.pop = function () {
    // return arr.splice(arr.length-1, 1)
    return arr.pop()
  }

  // 查看栈顶: peek()
  this.peek = function () {
    return arr[arr.length - 1]
  }
  // 栈中元素个数: size()
  this.size = function () {
    return arr.length
  }
  // 是否是空栈: isEmpty()
  this.isEmpty = function () {
    return arr.length===0
  }

  // 清栈
  this.clear = function () {
    arr = []
  }
}

用数组实现一个队列

先进先出

function Queue() {

  // 用于保存元素数据的数组
  const arr = []

  
  // 入队列: enqueue()
  this.enqueue = function (element) {
    arr.push(element)
  }

  // 出队列: dequeue()
  this.dequeue = function () {
    return arr.shift()
  }

  // 查看队头: front()
  this.front = function () {
    return arr[0]
  }
  // 查看元素的个数: size()
  this.size = function () {
    return arr.length
  }
  // 判断队列是否为空: isEmpty()
  this.isEmpty = function () {
    return arr.length===0
  }
}

数组扁平化

方法一 递归+concat+reduce

function flatten1(array){
    return array.reduce((initArray,item)=>{
        if(!Array.isArray(item)){
            initArray.push(item)
        }
        else{
            initArray = flatten1(item)
        }
        return initArray;
    },[])
}

方法二 some+concat

function flatten2(array){
   let arr = [].concat(...array)
   while(arr.some(item=>Array.isArray(arr))){
       arr = [].concat(...arr)
   }
   return arr;
}

方法三 toString+JSON.parse

function flatten3(array){
    return JSON.parse(array.toString()).map(item=>Number(item))
}

总结

1 数组的静态方法form,of,isArray作用分别是将伪数组转化为数组,将多个元素组合成数组,判断是否为Array类型

2 数组的实例方法包括影响原数组的(splice,reverse,push,shift,unshift,pop,sort)和不影响原数组的(forEach,some,every,map,reduce,find,slice,findIndex,indexOf,concat,find,filter,join)

3 面试中高发的题目数据去重数组扁平化找出数组中出现次数最多的元素队列