Skip to content

本章总结了一些跟 Array 相关的方法。

更多 API 的详细介绍,可见 MDN 网站

1.操作类

操作类指的是对数组实例进行操作的一类方法。

它们又可以细分为变异方法非变异方法

变异方法的概念来自于 Vue,它指的是调用该类方法之后,会影响原数组的方法。

而非变异方法自然是调用之后不会影响原数组的方法。

1-1.变异方法

  1. array.push()

向数组末尾添加一项:

js
var list = [1, 2, 3]
var result = list.push(4)
console.log(result) // 4
console.log(list) // [1, 2, 3, 4]
  1. array.pop()

向数组末尾截取一项:

js
var list = [1, 2, 3]
var result = list.pop()
console.log(result) // 3
console.log(list) // [1, 2]
  1. array.unshift()

向数组前端添加一项:

js
var list = [1, 2, 3]
var result = list.unshift(4)
console.log(result) // 4
console.log(list) // [4, 1, 2, 3]
  1. array.shift()

向数组前端截取一项:

js
var list = [1, 2, 3]
var result = list.shift()
console.log(result) // 1
console.log(list) // [2, 3]
  1. array.splice()

替换数组指定索引处的值:

js
var list = [1, 2, 3]
// 截取数组索引1 截取长度为2
var result = list.splice(1, 2)
console.log(result) // [2, 3]
console.log(list) // [1]
js
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]
  1. array.reverse()

数组倒序:

js
var list = [1, 2, 3]
var result = list.reverse()
console.log(result) // [3, 2, 1]
console.log(list) // [3, 2, 1]
  1. array.sort()

数组排序:

js
// 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 方法支持传一个函数,该函数可以自定义排序方式:

js
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.非变异方法

  1. array.slice()

slice 意为截取。它可以用来截取指定索引处的数据,并返回新数组。

js
// 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]
  1. array.concat()

concat 意为连接。它可以用来连接数组,并返回一个组成的新数组。

js
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']
  1. array.join()

join 意为拼接。它可以将数组中的各个元素以指定的符号拼接起来,组成一个字符串。

js
// 将数据以中文逗号","拼接起来
var list = ['hello', 'world']
var result = list.join(',')
console.log(result) // hello,world
console.log(list) // ['hello', 'world']

4. `array.toString`

2.遍历类

这里的遍历类方法指的是,需要对数组进行遍历操作。

  1. array.forEach()

forEach 可用来遍历数组。

forEach 无法使用 continue 或者 break 来打断循环。

如果想要实现 continue 的效果,可以在函数内使用 return 来阻断当前语句的继续执行,进而开始下一次的循环。

如果想要实现 break 的效果,可以使用 throw new Error() 结合 try...catch 语句来实现。

js
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')
  1. array.map()

map 方法可以用来将数组当中的每一项进行一次变形。

js
var personList = ['Tom', 'Jerry']
var result = personList.map(name => {
  return {
    name
  }
})
console.log(result) // [{name: 'Tom'}, {name: 'Jerry'}]
console.log(personList) // ['Tom', 'Jerry']
  1. array.filter()

filter 方法用来过滤满足条件下的数据。

js
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]
  1. array.some()

some 方法用来判断数组当中是否存在某一项满足特定条件。返回值为布尔值 truefalse

js
var list = [1, 2, 3, 4, 5]
var result = list.some(item => item > 3)
console.log(result) // true
  1. array.every()

every 方法用来判断数组当中是否每一项都满足特定条件。返回值为布尔值 truefalse

js
var list = [1, 2, 3, 4, 5]
var result = list.every(item => item > 3)
console.log(result) // false
  1. array.reduce()

reduce 意为减少。它是一个非常强大的数组方法。

它主要用来操作数组中的每一项,并返回一个精简后的结果。

假设有一个数组 [1, 2, 3, 4],我们要计算其中项的累加和。

按照我们以往的思路:

js
var list = [1, 2, 3, 4]
var sum = 0
list.forEach(item => {
  sum += item
})
console.log(sum) // 10

但如果使用 reduce 方法的话:

js
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:

js
// 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

  1. array.reduceRight()

reduceRightreduce 的区别在于从右往左遍历执行

篇幅原因,此处不作更多赘述。

  1. array.indexOf()

indexOf() 可以用来从左至右查找指定元素的索引。

函数返回值是指定元素的索引值。如果数组中没有该索引,返回值是 -1

js
var list = ['hello', 'world']
console.log(list.indexOf('world')) // 1
console.log(list.indexOf('i')) // -1
  1. array.lastIndexOf()

lastIndexOf() 可以用来从右至左查找指定元素的索引。

js
var list = ['hello', 'wolrd']
console.log(list.lastIndexOf('world')) // 0
console.log(list.lastIndexOf('i')) // -1
  1. array.find()

find()findIndex() 都是 Es6 中新增的数组方法。

这两者是为了弥补 indexOf() 的操作缺点。

find() 可以用来查找数组的指定元素。

js
var list = ['BeiJing', 'Olympics', '2022']
var value = list.find((item, index) => {
  return index > 0
})
console.log(value) // Olympics
  1. array.findIndex()
js
var list = ['BeiJing', 'Olympics', '2022']
var value = list.find(item => {
  return item === 'Olympics'
})
console.log(value) // 1
  1. array.flat()

flat() 会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

默认深度是 1

js
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 方法:

js
// 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])
  1. array.flatMap

flatMap() 可以看做 flat()map() 的结合体。但 flatMap() 的深度默认且只能是 1

js
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]]
  1. array.includes()

includes() 方法可用来判断数组内是否包含某一元素。

js
var list = [1, 2, 3, 4]
console.log(list.includes(3)) // true
console.log(list.includes(5)) // false