前言:看了很多文章都没有系统的总结一下Array常用的api,于是我产生了一个大胆的想法,总结了一些Array常用的api,以及面试中经常会被问到的数组相关的知识点。
开局一张图
部分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 面试中高发的题目数据去重
、数组扁平化
、找出数组中出现次数最多的元素
、栈
、队列
、