# 一、数组查找

  如果查找数据是否存在与数组中:建议用 includes;

  如果查找的数据的索引位置:建议用 indexOf。

注意

  其中,indexOf()includes()方法在字符串中也可以使用。

# 1、indexOf

Array.prototype.indexOf()

  方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。

const beasts = ['ant', 'bison', 'camel', 'duck', 'bison']

console.log(beasts.indexOf('bison'))
// expected output: 1

console.log(beasts.indexOf('giraffe'))
// expected output: -1
// 指定开始的索引位置
console.log(beasts.indexOf('bison', 2))
// expected output: 4
应用示例
  • 要求
输入: nums = [2,7,11,15], target = 9
输出: [0,1]
解释: 因为 nums[0] + nums[1] == 9 ,返回 [0, 1]
  • 解决
function twoSum(nums, target) {
  for (let i = 0; i < nums.length; i++) {
    let index = nums.indexOf(target - nums[i], i + 1)
    if (index != -1) {
      return [i, index]
    }
  }
}

// 等效于
function twoSum(nums, target) {
  for (let i = 0; i < nums.length; i++) {
    for (let j = i + 1; j < nums.length; j++) {
      if (nums[i] + nums[j] === target) {
        return [i, j]
      }
    }
  }
}

  需要注意的是,在处理某些复杂数组时,includes()方法不一定生效

  而 findIndex(cb)相较于 indexOf(),前者能处理根据复杂的问题,因为它接收的是一个回调函数

const data = [
  { name: 'John', age: 25 },
  { name: 'Jane', age: 30 },
  { name: 'Mike', age: 35 }
]

const person = [{ name: 'Jane', age: 30 }]

// 示例(some ==> includes)
if (data.some((item) => item.name === person.name)) {
  // 示例(findIndex => indexOf)
  const index = data.findIndex((item) => item.name === person.name)

  data[index].scores += 1
}

# 3、includes

Array.prototype.includes()

  用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false(即返回的是一个布尔值

const array1 = [1, 2, 3]

console.log(array1.includes(2))
// expected output: true

const pets = ['cat', 'dog', 'bat']

console.log(pets.includes('cat'))
// expected output: true

console.log(pets.includes('at'))
// expected output: false

  需要注意的是,在处理某些复杂数组时,includes()方法不一定生效

  此时我们就该使用 some()find()等进行代替。

# 3、应用与对比

应用:

// 白名单页面
const whiteList = ['/login', '/reg']

router.beforeEach((to, from, next) => {
  // 方式1
  if (whiteList.includes(to.path)) {
    next()
  }
  // 方式2
  if (whiteList.indexOf(to.path) !== -1) {
    next()
  }
})

对比:

var ary1 = new Array(3)
console.log(ary1.indexOf(undefined)) //-1
console.log(ary1.includes(undefined)) //true

# 二、元素排序

# 1、sort 方法

array.sort(compareFunction)

描述:

  用原地算法对数组的元素进行排序,并返回改变后的原数组

注意

  这种方法会改变原始数组!

即此时原数组和当前方法返回的数组一致

使用:

compareFn(a, b) 🎉 返回值 排序顺序
> 0 a 在 b 后
< 0 a 在 b 前
=== 0 保持 a 和 b 的顺序

# 2、使用示例

a - b 表示按 升序 排列(即:从小到大)

  • 数组内的数字排序
const numbers2 = [4, 2, 5, 1, 3]
numbers2.sort((a, b) => a - b)

console.log(numbers2)
// [1, 2, 3, 4, 5]
  • 对象中的属性值排序
const items = [
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: 'Magnetic', value: 13 },
  { name: 'Zeros', value: 37 }
]

// sort by value
items.sort((a, b) => a.value - b.value)

# 三、类型转换

join 和 split 是干什么的 ?

记忆

  站在字符串的角度:

  • join 将数组元素拼接成字符串
  • split 将字符串分割为数组

# 1、join 方法

描述:

  将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串

var a = ['Wind', 'Rain', 'Fire']

console.log(a.join()) // myVar1 的值变为"Wind,Rain,Fire"
var myVar2 = a.join(', ') // myVar2 的值变为"Wind, Rain, Fire"
var myVar3 = a.join(' + ') // myVar3 的值变为"Wind + Rain + Fire"
var myVar4 = a.join('') // myVar4 的值变为"WindRainFire"
var txt = ['小红', '小白', '小黄', '小黑', '小绿'] // 数组

console.log(txt.join(' ')) // '小红 小白 小黄 小黑 小绿'

// 拓展 —— toString方法
console.log(txt.tostring()) // '小红,小白,小黄,小黑,小绿'
// 相当于txt.join(',')的简写

# 2、split 方法

描述:

  使用指定的分隔符字符串将一个 String 对象分割成子字符串数组

var str = 'Hello World, Lencamo.'

var words = str.split(' ')
words // ['Hello', 'World,', 'Lencamo.']

var chars = str.split('')
chars[8] // 'r'
var str = 'a|b|c|d'

console.log(str.split('|')) // ['a', 'b', 'c', 'd']

# 四、截取数组

# 1、slice 方法 ✍

Array.prototype.slice([begin [, end]])

描述:

  返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括 end)

  • 使用示例
var arr = ['a', 'b', 'c', 'd', 'd']

// 常规
arr.slice() | arr.slice(0)
arr.slice(1) // ['b', 'c', 'd', 'd']
arr.slice(2) // ['c', 'd', 'd']
arr.slice(2, 3) // ['c']  ---》 常见的 前开后闭 区间

// 其他
arr.slice(-2) // ['d', 'd']
a.slice(6) // []

TIP

  slice 不会修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。

var fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango']
var citrus = fruits.slice(1, 3)

// fruits contains ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango']
// citrus contains ['Orange','Lemon']

  但如果原数组的元素是个对象引用,被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。

var myHonda = { color: 'red', wheels: 4, engine: { cylinders: 4, size: 2.2 } }

var myCar = [myHonda, 2, 'cherry condition', 'purchased 1997']
var newCar = myCar.slice(0, 2)

myHonda.color = 'purple'

console.log(myCar[0].color) // purple
console.log(newCar[0].color) // purple

myCar[0].color = 'green'

console.log(myHonda.color) // green
console.log(newCar[0].color) // green

应用:

  • 类数组对象转换为数组
// 1、arguments(函数部分讲过)
function list() {
  return Array.prototype.slice.call(arguments)
}

list(1, 2, 3) // [1, 2, 3]

// 2、其他(推荐使用后面的 Array.from() ✨ ---》 简单、功能强大)
Array.prototype.slice.call({ 0: 'a', 1: 'b', length: 2 })
Array.prototype.slice.call(document.querySelectorAll('div'))

# 2、filter 方法

描述:

  创建给定数组一部分的浅拷贝 (en-US),其包含通过所提供函数实现的测试的所有元素

let words = ['spray', 'limit', 'exuberant', 'destruction', 'elite', 'present']

const modifiedWords = words.filter((word, index, arr) => {
  arr[index + 1] += ' extra'
  return word.length < 6
})

# 3、扩展运算符

  用于可见的简单的数组截取。

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]

let [a, b, ...c] = arr
console.log(c) // [3, 4, 5, 6, 7, 8, 9]

  并且,如果在函数传参中使用扩展运算符时,其 args 也是一个数组:

function one(x, y = 666, ...data) {
  console.log(data) // [3, 4, 5, 6, 7]
}

one(1, 2, 3, 4, 5, 6, 7)

# 五、去重

# 1、数组合并

  • concat 方法
var arr1 = [1, 2, 3]
var arr2 = [4, 5, 6]
var arr3 = [7, 8, 9]

var numbers = arr1.concat(arr2)
var numbers = arr1.concat(arr2, arr3)
  • 扩展运算符
var arr1 = [1, 2, 3]
var arr2 = [4, 5, 6]

let numbers = [...arr1, ...arr2]

# 2、数组去重

  forEach()去重时,

var arr = [1, 2, 2, 3, 5, 6, 6]

// 1、遍历去重
// for、forEach等
var arr2 = []
for (var i = 0; i < arr.length; i++) {
  // 使用indexof / includes
  if (arr2.indexof(arr1[i]) === -1) {
    arr2.push(arr1[i])
  }
}
console.log(arr2)

// filter、reduce等
var arr3 = arr.filter((item, index) => {
  return arr.indexOf(item) === index
})

var arr3 = arr.reduce((pre, cur) => {
  if (pre.indexOf(cur) === -1) {
    pre.push(cur)
  }
  return pre
}, [])
console.log(arr3)

// 2、利用 set ✨
var arr2 = Array.from(new Set(arr1))
// 或者
var arr2 = [...new Set(arr1)]

console.log(arr2)

# 六、其他 ES6 语法

# 2、扁平化处理

# ① flat()

  flat() 方法创建一个新的数组,并根据指定深度递归地将所有子数组元素拼接到新的数组中。

要提取嵌套数组的结构深度默认值为 1。

let arr = [['a', 'b'], 'h', ['e', 'f', 'g']]

console.log(arr.flat()) //  ['a', 'b', 'h', 'e', 'f', 'g']
let arr = [0, 1, 2, [[[3, 4]]]]

console.log(arr.flat(3)) //  [0, 1, 2, 3, 4]

# ② flatMap()

  flatMap() 相较于 flat()可以处理根据复杂的扁平化需求。

let arr = [
  {
    id: 1,
    list: ['安阳', '南阳', '洛阳']
  },
  {
    id: 2,
    list: ['北京', '天津', '南京']
  }
]

let arr1 = arr.flatMap(function (item) {
  return item.list
})
console.log(arr1) // ['安阳', '南阳', '洛阳', '北京', '天津', '南京']

  它和 map()方法相似,但也有些许不同(重点理解扁平化处理的意思):

代码理解
var arr = [1, 2, 3, 4]

arr.map((x) => [x * 2])
// [[2], [4], [6], [8]]

arr.flatMap((x) => [x * 2])
// [2, 4, 6, 8]

// 拓展:替代方案🤔
arr.reduce((preV, curV) => preV.concat([curV * 2]), [])
// [2, 4, 6, 8]
let arr = ["I'm lencamo", '', 'note-taking']

arr.map((x) => x.split(' '))
// [["I'm","lencamo"],[""],["note-taking"]]

arr.flatMap((x) => x.split(' '))
// ["I'm", 'lencamo', '', 'note-taking']

# 3、fill( ) 方法

  对于 fill() 方法,是用指定的值来填充原始数组的元素。

array.fill(value, [start, end));

let arr = ['🐱', '🐶', '🐰', '🐍', '🐦', '🐟']

let result = arr.fill('🐷') // ['🐷', '🐷', '🐷', '🐷', '🐷', '🐷']
let result = arr.fill('🐷', 2) // ['🐱', '🐶', '🐷', '🐷', '🐷', '🐷']
let result = arr.fill('🐷', 2, 4) // ['🐱', '🐶', '🐷', '🐷', '🐦', '🐟']
console.log(result)

  其实在字符串的也有类似重复效果的方法:

repeat()方法

  repeat() 构造并返回一个新字符串,该字符串包含被连接在一起的指定数量的字符串的副本。

let elmStr = `<span>span标签的内容</span>`

let newStr = elmStr.repeat(3)
// "<span>span标签的内容</span><span>span标签的内容</span><span>span标签的内容</span>"

# 4、Array.of 数组

  Array.of() 静态方法通过可变数量的参数创建一个新的 Array 实例,而不考虑参数的数量或类型。

console.log(Array.of('foo', 2, 'bar', true))
// Expected output: Array ["foo", 2, "bar", true]

  它的出现是为了解决下面的问题:

但是说实话,我正的要创建一个数组,直接写[3]创建数据不就得了吗,还干嘛呀使用 new Array

// 目标:[3]
const arr = new Array(3) // [ , , ,]

// 解决1
const arr1 = new Array()
arr.push(3) // 1
console.log(arr) // [3]

// 解决2
const arr = Array.of(3) // [3]

# 七、ES2023 新增方法

  ES2023 题案链接:https://github.com/tc39/proposals/blob/master/finished-proposals.md (opens new window)

# 1、元素查找

向后查找:

  • Array.prototype.findLast()
  • Array.prototype.findLastIndex()
// 对应以前的:
Array.prototype.find()
Array.prototype.findIndex()

# 2、数组方法

非破坏性方法:

  • toSored()
  • toReversed()
  • toSpliced()
  • with()
// 对应以前的:
Array.prototype.sort()
Array.prototype.reverse()
Array.prototype.splice()
Array.prototype.concat()
更新于 : 8/7/2024, 2:16:31 PM