本章总结了一些跟 Array
相关的方法。
更多 API
的详细介绍,可见 MDN
网站。
1.操作类
操作类指的是对数组实例进行操作的一类方法。
它们又可以细分为变异方法与非变异方法。
变异方法的概念来自于 Vue
,它指的是调用该类方法之后,会影响原数组的方法。
而非变异方法自然是调用之后不会影响原数组的方法。
1-1.变异方法
array.push()
向数组末尾添加一项:
var list = [1, 2, 3]
var result = list.push(4)
console.log(result) // 4
console.log(list) // [1, 2, 3, 4]
array.pop()
向数组末尾截取一项:
var list = [1, 2, 3]
var result = list.pop()
console.log(result) // 3
console.log(list) // [1, 2]
array.unshift()
向数组前端添加一项:
var list = [1, 2, 3]
var result = list.unshift(4)
console.log(result) // 4
console.log(list) // [4, 1, 2, 3]
array.shift()
向数组前端截取一项:
var list = [1, 2, 3]
var result = list.shift()
console.log(result) // 1
console.log(list) // [2, 3]
array.splice()
替换数组指定索引处的值:
var list = [1, 2, 3]
// 截取数组索引1 截取长度为2
var result = list.splice(1, 2)
console.log(result) // [2, 3]
console.log(list) // [1]
var list = [1, 2, 3]
// 截取数组索引1 截取长度为2 并加入4
var result = list.splice(1, 2, 4)
console.log(result) // [2, 3]
console.log(list) // [1, 4]
array.reverse()
数组倒序:
var list = [1, 2, 3]
var result = list.reverse()
console.log(result) // [3, 2, 1]
console.log(list) // [3, 2, 1]
array.sort()
数组排序:
// sort方法默认会以原地算法对数组中的数据进行排列
var months = ['March', 'Jan', 'Feb', 'Dec']
console.log(months.sort()) // ['Dec', 'Feb', 'Jan', 'March']
console.log(months) // ['Dec', 'Feb', 'Jan', 'March']
var list = [1, 30, 4, 21, 100000]
console.log(list.sort()) // [1, 100000, 21, 30, 4]
console.log(list) // [1, 100000, 21, 30, 4]
sort
方法支持传一个函数,该函数可以自定义排序方式:
var months = ['March', 'Jan', 'Feb', 'Dec']
var list = [1, 30, 4, 21, 100000]
// 比较纯字符串
var compareStrFn = function (a, b) {
if (a < b) {
return -1
}
if (a > b) {
return 1
}
return 0
}
// !!!如果是比较数字的话 函数才可以简写成:(如果该函数用作比较字符串,不会起作用,根本原因在于'March' 'Jan'这类字符串无法作减法运算 而'1' '30'这类数字字符串是可以的哟)
var compareNumFn = function (a, b) {
// a => 数组的后一位元素 b => 数组的前一位元素
// 返回值大于0 升序排列,返回值小于0 降序排列
return a - b
}
console.log(months.sort(compareStrFn)) // ['Dec', 'Feb', 'Jan', 'March']
console.log(list.sort(compareNumFn)) // [1, 4, 21, 30, 100000]
1-2.非变异方法
array.slice()
slice
意为截取。它可以用来截取指定索引处的数据,并返回新数组。
// 1.截取[1, ∞)的数据
var list = [1, 2, 3, 4]
var result = list.slice(1)
console.log(result) // [2, 3, 4]
console.log(list) // [1, 2, 3, 4]
// 2.截取[1, 3)的数据
var list = [1, 2, 3, 4]
var result = list.slice(1, 3)
console.log(result) // [2, 3]
console.log(list) // [1, 2, 3, 4]
array.concat()
concat
意为连接。它可以用来连接数组,并返回一个组成的新数组。
var dayList = ['monday', 'tuesday']
var foodList = ['milk', 'bread']
var result = dayList.concat(foodList)
console.log(result) // ['monday', 'tuesday', 'milk', 'bread']
console.log(dayList) // ['monday', 'tuesday']
console.log(foodList) // ['milk', 'bread']
array.join()
join
意为拼接。它可以将数组中的各个元素以指定的符号拼接起来,组成一个字符串。
// 将数据以中文逗号","拼接起来
var list = ['hello', 'world']
var result = list.join(',')
console.log(result) // hello,world
console.log(list) // ['hello', 'world']
4. `array.toString`
2.遍历类
这里的遍历类方法指的是,需要对数组进行遍历操作。
array.forEach()
forEach
可用来遍历数组。
forEach
无法使用 continue
或者 break
来打断循环。
如果想要实现 continue
的效果,可以在函数内使用 return
来阻断当前语句的继续执行,进而开始下一次的循环。
如果想要实现 break
的效果,可以使用 throw new Error()
结合 try...catch
语句来实现。
var dayList = ['Friday', 'Saturday', 'Sunday']
// 1.实现continue
dayList.forEach(item => {
console.log(item)
if (item === 'Saturday') {
return
}
console.log(`The day is ${item}`)
})
// 2.实现break
try {
dayList.forEach(item => {
console.log(item)
if (item === 'Saturday') {
throw new Error(item)
}
console.log(`The day is ${item}`)
})
} catch(e) {
console.error(e)
}
// 添加try...catch之后 才能保证后续语句不受抛错影响 能够继续执行。
console.log('Hello world')
array.map()
map
方法可以用来将数组当中的每一项进行一次变形。
var personList = ['Tom', 'Jerry']
var result = personList.map(name => {
return {
name
}
})
console.log(result) // [{name: 'Tom'}, {name: 'Jerry'}]
console.log(personList) // ['Tom', 'Jerry']
array.filter()
filter
方法用来过滤满足条件下的数据。
var list = [1, 2, 3, 4, 5]
var result = list.filter(item => item > 3)
console.log(result) // [4, 5]
console.log(list) // [1, 2, 3, 4, 5]
array.some()
some
方法用来判断数组当中是否存在某一项满足特定条件。返回值为布尔值 true
或 false
。
var list = [1, 2, 3, 4, 5]
var result = list.some(item => item > 3)
console.log(result) // true
array.every()
every
方法用来判断数组当中是否每一项都满足特定条件。返回值为布尔值 true
或 false
。
var list = [1, 2, 3, 4, 5]
var result = list.every(item => item > 3)
console.log(result) // false
array.reduce()
reduce
意为减少。它是一个非常强大的数组方法。
它主要用来操作数组中的每一项,并返回一个精简后的结果。
假设有一个数组 [1, 2, 3, 4]
,我们要计算其中项的累加和。
按照我们以往的思路:
var list = [1, 2, 3, 4]
var sum = 0
list.forEach(item => {
sum += item
})
console.log(sum) // 10
但如果使用 reduce
方法的话:
var list = [1, 2, 3, 4]
var sum = list.reduce((a, b) => a + b)
console.log(sum) // 10
reduce
的基本语法如下:
arr.reduce(callback(accumulator, currentValue, index, array), initialValue)
它的参数解释如下:
accumulator
累计值。第一次循环开始时,如果没有initialValue
的话,默认取数组第一项,否则取initialValue
。后续循环取callback
的返回值。currentValue
数组中正在处理的元素。index
数组中正在处理的当前元素的索引。如果提供了initialValue
,则起始索引号为0
,否则从索引1
起始。array
调用reduce()
的数组。initialValue
作为第一次调用callback
函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。在没有初始值的空数组上调用reduce
将报错。
为了更好的看到 reduce
的威力,我们实现几个 demo
:
// 1.累加对象数组里的值
var list = [{num: 10}, {num: 19}, {num: 1}]
var sum = list.reduce((a, b) => {
console.log(a, b)
return a + b.num
}, 0)
console.log(sum) // 30
// 2.将二维数组转化为一组
var list = [[1, 2], [3, 4]]
var result = list.reduce((a, b) => {
return a.concat(b)
})
console.log(result) // [1, 2, 3, 4]
// 3.计算数组中每个元素出现的次数
var list = ['Friday', 'Saturday', 'Sunday', 'Saturday']
var result = list.reduce((a, b) => {
if (b in a) {
a[b] += 1
} else {
a[b] = 1
}
return a
}, {})
console.log(result) // {Friday: 1, Saturday: 2, Sunday: 1}
// 4.按照属性给Object分类
var people = [
{ name: 'Alice', age: 21 },
{ name: 'Max', age: 20 },
{ name: 'Jane', age: 20 }
]
var result = people.reduce((a, b) => {
var index = a.findIndex(item => {
return item.some(i => i.age === b.age)
})
if (index > -1) {
a[index].push(b)
} else {
a[a.length] = [b]
}
return a
}, [])
console.log(result) // [[{ name: 'Alice', age: 21 }], [{ name: 'Max', age: 20 }, { name: 'Jane', age: 20 }]]
// 5.数组去重
var list = [1, 1, 2, 3, 3, 4, 4]
var result = list.reduce((a, b) => {
if (!a.includes(b)) {
a.push(b)
}
return a
}, [])
console.log(result) // [1, 2, 3, 4]
更多 reduce
调用细节可参见MDN
array.reduceRight()
reduceRight
与 reduce
的区别在于从右往左遍历执行。
篇幅原因,此处不作更多赘述。
array.indexOf()
indexOf()
可以用来从左至右查找指定元素的索引。
函数返回值是指定元素的索引值。如果数组中没有该索引,返回值是 -1
。
var list = ['hello', 'world']
console.log(list.indexOf('world')) // 1
console.log(list.indexOf('i')) // -1
array.lastIndexOf()
lastIndexOf()
可以用来从右至左查找指定元素的索引。
var list = ['hello', 'wolrd']
console.log(list.lastIndexOf('world')) // 0
console.log(list.lastIndexOf('i')) // -1
array.find()
find()
和 findIndex()
都是 Es6
中新增的数组方法。
这两者是为了弥补 indexOf()
的操作缺点。
find()
可以用来查找数组的指定元素。
var list = ['BeiJing', 'Olympics', '2022']
var value = list.find((item, index) => {
return index > 0
})
console.log(value) // Olympics
array.findIndex()
var list = ['BeiJing', 'Olympics', '2022']
var value = list.find(item => {
return item === 'Olympics'
})
console.log(value) // 1
array.flat()
flat()
会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
默认深度是 1
。
var list = [1, 2, [[3, 4]]]
console.log(list.flat()) // [1, 2, [3, 4]]
console.log(list.flat(2)) // [1, 2, 3, 4]
使用其他 API
来模拟实现 flat
方法:
// 1.reduce
var list = [1, 2, [[3, 4]]]
Array.prototype.flat = function (deep = 1) {
return deep > 0 ? this.reduce((accum, current) => {
return Array.isArray(current) ? accum.concat(current.flat(--deep)) : accum.concat(current)
}, []) : this.concat([])
}
list.flat()
// 2.迭代器 生成器
var list = [1, 2, [[3, 4]]]
function* generator (list) {
for (var item of list) {
if (Array.isArray(item)) {
yield* generator(item)
} else {
yield item
}
}
}
var iterator = generator(list)
console.log([...iterator])
array.flatMap
flatMap()
可以看做 flat()
与 map()
的结合体。但 flatMap()
的深度默认且只能是 1
。
var list = [1, 2, 3, 4]
console.log(list.map(item => [item * 2])) // [[2], [4], [6], [8]]
console.log(list.flatMap(item => [item * 2])) // [2, 4, 6, 8]
console.log(list.flatMap(item => [[item * 2]])) // [[2], [4], [6], [8]]
array.includes()
includes()
方法可用来判断数组内是否包含某一元素。
var list = [1, 2, 3, 4]
console.log(list.includes(3)) // true
console.log(list.includes(5)) // false