# 一、数组查找
如果查找数据是否存在与数组中:建议用 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()