数组Array使用详解
认识数组(Array)
◼ 什么是数组(Array)呢?
对象允许存储键值集合,但是在某些情况下使用键值对来访问并不方便;
比如说一系列的商品、用户、英雄,包括HTML元素,我们如何将它们存储在一起呢?
这个时候我们需要一种有序的集合,里面的元素是按照某一个顺序来排列的;
这个有序的集合,我们可以通过索引来获取到它;
这个结构就是数组(Array);
◼ 数组和对象都是一种保存多个数据的数据结构,在后续的数据结构中我们还会学习其他结构;
◼ 我们可以通过[]来创建一个数组:
数组是一种特殊的对象类型;
var letters = ["A","B","c","d"]
数组的创建方式
◼ 创建一个数组有两种语法:
var arr1 = []
var arr2 = new Array()
◼ 下面的方法是在创建一个数组时,设置数组的长度(很少用)
var arr2 = new Array(5)
console.log(arr2)
◼ 数组元素从0 开始编号(索引index)。
一些编程语言允许我们使用负数索引来实现这一点,例如fruits[-1]
JavaScript并不支持这种写法;
数组的基本操作:
访问数组中的元素;
通过中括号[]访问
arr.at(i):
✓ 如果i>= 0,则与arr[i] 完全相同。
✓ 对于i为负数的情况,它则从数组的尾部向前数。
console.log(arr[1])
console.log(name.at(-1))
访问最后一个:console.log(arr[arr.length - 1])
修改数组中的元素;
arr[1] = "aaa"
新增删除数组
◼ 在数组的尾端添加或删除元素:
push 在末端添加元素.
pop从末端取出一个元素.
var names = ["abc","bcd","efg"];
// 在尾部添加和删除元素
// push方法添加
names.push("hdc","kobe");
console.log(names)
// pop方法删除
names.pop()
console.log(names)
◼ 在数组的首端添加或删除元素
shift 取出队列首端的一个元素,整个数组元素向前前移动;
unshift 在首端添加元素,整个其他数组元素向后移动;
// 在数组头部添加和删除元素
// unshift方法在头部添加多个元素
names.unshift("hdc","james")
console.log(names)
// shiftf方法删除头部一个元素
names.shift()
console.log(names)
◼ push/pop 方法运行的比较快,而shift/unshift 比较慢。
◼ 如果我们希望在中间某个位置添加或者删除元素应该如何操作呢?
◼ arr.splice 方法可以说是处理数组的利器,它可以做所有事情:添加,删除和替换元素。
◼ arr.splice的语法结构如下:
array.splice()
从start位置开始,处理数组中的元素;
deleteCount:要删除元素的个数,如果为0或者负数表示不删除;
item1, item2, ...:在添加元素时,需要添加的元素;
// 第三个在任意位置添加/删除/替换
// 1.删除一个元素
names.splice(1,1)
// 2.新增两个元素
names.splice(1,0,"abc","abcd")
// 3.替换两个元素
names.splice(1,2,"kobe","curry")
◼ 注意:这个方法会修改原数组
数组的length属性
◼ length属性用于获取数组的长度:
当我们修改数组的时候,length 属性会自动更新。
◼ length 属性的另一个有意思的点是它是可写的。
如果我们手动增加一个大于默认length的数值,那么会增加数组的长度。
但是如果我们减少它,数组就会被截断。
arr.length = 10;
console.log(arr)//长度:10
arr.length = 2;
console.log(arr)//长度:2
◼ 所以,清空数组最简单的方法就是:arr.length = 0;。
数组遍历
// 数组遍历
//1. 普通for循环
for (var i = 0;i<names.length;i++){
console.log(names[i])
}
// 2. for in
for (var abc in names){
console.log(abc)//索引
}
// 3. for of ---->拿不到索引值
for (const element of names) {
console.log(element)//数组值
}
数组方法–slice、concat、 join
◼ arr.slice 方法:用于对数组进行截取(类似于字符串的slice方法)。
arr.slice(begin,end)
包含bigin元素,但是不包含end元素;
console.log(arr.slice(2,3))
◼ arr.concat方法:创建一个新数组,其中包含来自于其他数组和其他项的值。
var newArr = arr.concat(["abc","cba"],"nba")
◼ arr.join方法: 将一个数组的所有元素连接成一个字符串并返回这个字符串。
console.log(arr.join("*"))
数组方法–查找元素
◼ arr.indexOf方法: 查找某个元素的索引
从fromIndex开始查找,如果找到返回对应的索引,没有找到返回-1;
也有对应的从最后位置开始查找的lastIndexOf方法
◼ arr.includes方法:判断数组是否包含某个元素
从索引from 开始搜索item,如果找到则返回true(如果没找到,则返回false)。
◼ find 和 findIndex 直接查找元素或者元素的索引(ES6之后新增的语法)
//2.使用find:高阶函数-->函数本身接受另外的函数作为参数
var stu1 = student.find(function(item,index,arr){
return item.id === 101
})
console.log(stu1)
//查找元素
names.findIndex(function(item,index,arr)){
return item === "nba"
}
数组的排序–sort/reverse
◼ sort方法也是一个高阶函数,用于对数组进行排序,并且生成一个排序后的新数组:
如果compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 前面;
如果compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变;
如果compareFunction(a, b) 大于 0 , b 会被排列到 a 前面;
也就是说,谁小谁排在前面;
nums.sort(function(item1,item2){
// item 和 item2 进行比较
// 返回是正数
return item1 - item2
})
◼ 等到后续讲解数据结构与算法时,我们会编写自己的排序算法:
冒泡排序、插入排序、选择排序、堆排序、希尔排序、快速排序等
◼ reverse() 方法将数组中元素的位置颠倒,并返回该数组。
console.log(nums.reverse() )
数组的其他高阶方法
◼ arr.forEach
遍历数组,并且让数组中每一个元素都执行一次对应的方法;
◼ arr.map
map() 方法创建一个新数组;
这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成;
◼ arr.filter
filter() 方法创建一个新数组;
新数组中只包含每个元素调用函数返回为true的元素;
◼ arr.reduce
用于计算数组中所有元素的总和;
对数组中的每个元素按序执行一个由您提供的reducer函数;
每一次运行reducer会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值;
案例:
// 1.forEach函数
var names = ["abc", "cba", "nba", "mba"]
// 三种方式, 新增一种方式
// names.forEach(function(item) {
// console.log(item, this)
// }, { name: "why" })
// 2.filter函数: 过滤
// var nums = [11, 20, 55, 100, 88, 32]
// 2.1. for循环实现
// var newNums = []
// for (var item of nums) {
// if (item % 2 === 0) {
// newNums.push(item)
// }
// }
// console.log(newNums)
// 2.2. filter实现
// var newNums = nums.filter(function(item) {
// return item % 2 === 0
// })
// console.log(newNums)
// 3.map函数: 映射
// var nums = [11, 20, 55, 100, 88, 32]
// var newNums = nums.map(function(item) {
// return item * item
// })
// console.log(newNums)
// 4.reduce
// var nums = [11, 20, 55, 100, 88, 32]
// var result = 0
// for (var item of nums) {
// result += item
// }
// console.log(result)
// 第一次执行: preValue->0 item->11
// 第二次执行: preValue->11 item->20
// 第三次执行: preValue->31 item->55
// 第四次执行: preValue->86 item->100
// 第五次执行: preValue->186 item->88
// 第六次执行: preValue->274 item->32
// 最后一次执行的时候 preValue + item, 它会作为reduce的返回值
// initialValue: 初始化值, 第一次执行的时候, 对应的preValue
// 如果initialValue没有传呢?
// var result = nums.reduce(function(preValue, item) {
// console.log(`preValue:${preValue} item:${item}`)
// return preValue + item
// }, 0)
// console.log(result)
// reduce练习
// var products = [
// { name: "鼠标", price: 88, count: 3 },
// { name: "键盘", price: 200, count: 2 },
// { name: "耳机", price: 9.9, count: 10 },
// ]
// var totalPrice = products.reduce(function(preValue, item) {
// return preValue + item.price * item.count
// }, 0)
// console.log(totalPrice)
// 综合练习:
var nums = [11, 20, 55, 100, 88, 32]
// 过滤所有的偶数, 映射所有偶数的平方, 并且计算他们的和
// var total = nums.filter(function(item) {
// return item % 2 === 0
// }).map(function(item) {
// return item * item
// }).reduce(function(preValue, item) {
// return preValue + item
// }, 0)
// console.log(total)
// var total = nums.filter(item => item % 2 === 0)
// .map(item => item * item)
// .reduce((preValue, item) => preValue + item, 0)
// console.log(total)