javascript基础系列:数组常用方法解析

600 阅读6分钟

今天是比较特殊的日子,我们编程人员共同的节日,1024,祝每个编程人员节日快乐!

数组是javascript必不可少的一项,今天让我们来总结一下数组操作的一些常用方法。

数组及数组中常用方法

数组是对象类型的,属于特殊的对象

let ary = [12, 23, 34, 45]
console.log(typeof Ary) // =>"object"
console.dir(ary)  // 1. 数字作为索引(key属性名) 2. length代表长度


数组中常用的方法

  • 方法的作用和含义
  • 方法的实参(类型和含义)
  • 方法的返回值
  • 原来的数组是否发生改变
1. 实现数组增删改的方法

这一部分方法都会修改原有的数组

push

push:向数组末尾添加内容 @params 多个任意类型 @return 新增后数组的长度

let ary = [10, 20]
let res = ary.push(12, 30)
console.log(res) //4
console.log(ary) // [10, 20, 12, 30
// 基于原生js操作键值对的方法,也可以向末尾追加一项新的内容
ary[ary.length] = 40
console.log(ary)

unshift

unshift:向数组开始位置添加内容 @params 多个任意类型 @return 新增后数组的长度

let ary = [10, 20]
let res = ary.unshift(12, 30)
console.log(res) //4
console.log(ary) // [10, 20, 12, 30]
// 基于原生ES6展开运算符,把原有的ary克隆一份,在新的数组中创建第一项,其余的内容使用原始ary中的信息即可,也算
//实现了向开始追加的效果
ary = [100, ...ary]
console.log(ary)

shift

shift:删除数组中的第一项 @params @return 删除的那一项

let ary = [10, 20, 12, 30]
let res = ary.shift()
console.log(res, ary) // 10 [20, 12, 30]

基于原生js中的delete,把数组当成普通的对象,确实可以删除掉某一项内容,但是不会影响数组本身的结构特点(length长度不会跟着修改),真实项目中杜绝这样的删除使用

pop

pop:删除数组中的最后一项 @params

@return 删除的那一项

let ary = [10, 20, 30, 40]
let res = ary.pop();
console.log(res, ary) // 40, [10, 20, 30]


基于原生js让数组长度去掉一位,默认删除最后一项

let ary = [10, 20, 30, 40]
ary.length--;
console.log(ary)


splice

splice:实现数组的增加、删除、修改 @params n, m都是数字, 从索引n开始删除m个元素(m不写,是删除到末尾) n,m,x , 从索引n开始删除m个元素,用x占用删除的部分 n, 0, x从索引n开始,一个都不删,把x放到索引n的前面 @return 把删除的部分用新数组存储起来返回

let ary = [10, 20, 30, 40]
let res = ary.splice(2,2)
console.log(res, ary)
// 基于这种方法可以清空一个数组,把原始数组中的内容以新数组存储起来
//ary.splice(0)


// 删除最后一项和第一项
ary.splice(ary.length-1)
ary.splice(0,1)
console.log(ary)

// 向数组末尾追加
ary.splice(ary.length,0, 'aaa')

//向数组开始追加
ary.splice(0,0,'aaa')

2. 数组的查询和拼接

此组方法,原来数组不会改变

slice

slice: 实现数组的查询 @params n, m都是数字,从索引n开始,找到索引为m的地方(不包括m) @return 把找到的内容以一个新数组的形式返回

let ary = [10, 20, 30, 40, 50]
let res = ary.slice(1, 3)
console.log(res, ary) // [20, 30] [10, 20, 30, 40, 50]

// 数组克隆,参数0可以不写,浅克隆
let res2 = ary.slice(0)

concat

slice: 实现数组的拼接 @params 多个热任意类型值 @return 拼接后新的数组(原来的数组不变)

let ary1 = [10, 20, 30]
let ary2 =  [40, 50, 60]
let res = ary1.concat('岚枫', ary2);
console.log(res)

3. 把数组转化为字符串

原有数组不变

toString

toString: 把数组转换为字符串 @params @return 转换后的字符串,每一项用逗号分隔(原来的数组不变)

let ary = [10, 20, 30]
let res = ary.toString();
console.log(res) // "10, 20, 30"
console.log([].toString()) // ""

join

join: 把数组转换为字符串 @params 指定的分隔符(字符串格式) @return 转换后的字符串,每一项用指定分隔符分隔(原来的数组不变)

let ary = [10, 20, 30]
let res = ary.join(' ');
console.log(res) // "10 20 30"

4. 检测数组中是否包含某一项

indexOf/lastIndexOf

indexOf/lastIndexOf: 检测当前项在数组中第一次或者最后一次索引值,(在ie6-8中不兼容) @params 要检索的这一项内容 @return 这一项出现的位置索引值(数字),如果数组中没有这一项,返回的结果是-1

let ary = [10, 20, 30, 10, 20, 30]
console.log(ary.indexOf(20)) // 1
console.log(ary.lastIndexOf(20)) // 4
// 验证ary数组是否包含‘岚枫’
if(ary.indexOf('岚枫') === -1) {
	//不包含
}
// 直接使用ES6新提供的includes方法判断
if(ary.includes('岚枫')) {
	//	包含:如果存在返回的是true
}

5. 数组的排序或者排列

reverse

reverse:把数组倒过来排列 @return 排列后的新数组,原来的数组改变

let ary = [12, 15, 9, 28]
ary.reverse();
console.log(ary)

sort

sort:实现数组的排序 @params 可以没有,也可以是个函数 @return 排列后的新数组,原来的数组改变

如果不传参数,是无法处理10以上的数字排序(它默认都是按照第一个字符来排)

// 想要实现多位数正常排序,需要给sort传递一个函数,函数中返回a-b升序,返回b-a实现降序
let ary = [10, 12, 15,22, 28, 9]
ary.sort((a, b) => {
  // a和b是相邻的两项
	 return a-b
})
console.log(ary)

6. 遍历数组中的每一项方法

forEach

forEach: 遍历数组中的每一项内容 @params 回调函数 @return 原来的数组不变

let ary = [12, 15, 9, 28, 10, 22]

//基于原生js中的循环可以实现
for(let i=0; i< ary.length; i++) {
	// i: 当前循环这一项的索引
  //ary[i]: 根据索引获取循环的这一项
}

ary.forEach((item, index)=> {
  // 数组中有多少项,函数就会被默认执行多少次
  // 每一次执行函数: item是数组中当前要操作的这一项,index是当前的索引值
})

map
filter
find
reduce
some
every

数组中的去重

1. 方案一
  1. 循环原有数组中的每一项,每拿到一项都往新数组中添加
  2. 添加之前验证新数组中是否存在这一项,不存在再增加
let ary = [1, 2,3, 1, 2, 1, 2, 1, 2, 3, 2, 1, 2, 3]
let newAry = [];
for(let i = 0; i< ary.length; i++) {
  
  // 循环获取原有数组中的每一项
	let item = ary[i]
  
  // 验证新数组中是否存在这一项
  if(newAry.includes(item)) {
    // 存在这一项,不再增加到新数组中,继续下一轮循环即可
  	continue;
  }
  newAry.push(item)
}
console.log(newAry)

image.png

2. 方案二
  1. 先分别拿出数组中的每一项
  2. 用这一项和它后面的每一项依次进行比较,如果遇到和当前项相同的,则在原来数组中把这一项从数组中删除,用splice方法
var ary = [1, 2,3, 1, 2, 1, 2, 1, 2, 3, 2, 1, 2, 3];
for(var i = 0 ; i < ary.length; i++) {
  
  // item: 每一次循环拿出来的当前项
	var item = ary[i];
  // 让当前项和后面的每一项进行比较(循环)
  for(var j= i+1; j< ary.length; j++) {
  	var compare = ary[j];
    
    // 如果compare和item相等,说明这一项是重复的,我们把它删掉
    if(compare === item) {
    	// j索引这一项要从数组中删除
      ary.splice(j, 1);
      
      // 数组塌陷了: j后面的每一项索引都提前了一位,下一次要比较的应该还是j这个索引内容
      j--;
    }
  }
}

image.png

3. 数组中去重比较好的方法
let ary = [1,  2, 3, 1, 2, 1, 2, 3, 2, 1, 2, 3]

  // 1. 创建一个空对象
let obj = {}

// 2. 循环数组中的每一项,把每一项对象中进行存储 =》 item: item
for(let i=0; i< ary.length; i++) {
	let item = ary[i]
  
  //3. 每一次存储之前进行判断:验证obj中是否存在这一项
  if(obj[item] !== undefined) {
   // 已经存在这一项
    ary[i] = ary[ary.length-1]
    ary.length--;
    i--;
    continue;
  }
  obj[item] = item
  
}
console.log(ary)

基于splice实现删除性能不好:当前项被删除后,后面的每一项的索引都要向前提一位,如果后面内容过多,一定影响性能
实现数组去重的方法

unique: 实现数组去重的方法 @params ary[Array]要去重的数组 @return [Array] 去重后的数组

function unique(ary){
	let obj = {}
  for(let i=0; i< ary.length; i++) {
  let item = ary[i]
  if(obj[item] !== undefined) {
    ary[i] = ary[ary.length-1]
    ary.length--;
    i--;
  	continue;
  }
  obj[item] = item
  }
  return ary
}
console.log(unique([1,1,2,2,4,4]))

4. 基于ES6的Set去重方法
let ary = [12, 23, 12, 15, 25,23, 25, 14, 16]
ary = [... new Set(ary)];
console.log(ary)