数组
字面理解就是一组数据的集合
js的数组成员可以是任意类型的数据
数组可以动态扩容
创建数组
字面量创建(推荐使用)
语法:
var 数组名 = []
注:
数据之间用","隔开
例:
var arr = [11,22,33,44]
console.log(arr) //(4) [11, 22, 33, 44]
构造函数创建
语法:
var 数据名 = new Array()
例:
var arr = new Array(11,22)
console.log(arr) //(2) [11, 22]
var arr = new Array(10)
console.log(arr) //(10) [empty × 10]
注:
如果Array里有一个参数,并且是数值类型,表示数组的初始值长度,值都为empty(空)
数组长度与下标
获取数组长度
语法:
语法:数组名.length
例:
var arr = [11,22,33,44,55]
console.log(arr.length) //5
注:数组长度可以被修改,**会丢失数据**
例:
var arr = [11, 22, 33, 44];
arr.length = 1;
console.log(arr) //[11]
arr.length = 4;
console.log(arr); //(4) [11, empty × 3]
下标(索引)
语法:数组名[下标值]
- 通过数组的下标可以获取或修改指定位置的元素
- 下标的取值范围为0~数组长度-1
// 索引从0开始
var arr = [11, 22, 33]
// 通过下标取值
console.log(arr[1]) //22
// 通过下标修改值
arr[0] = "aaa"
console.log(arr) //(3) ['aaa', 22, 33]
数组方法
- 常用方法:20个
es3(10个)pop,push,shift,unshift,sort,reverse,slice,splice,concat,join
es5高阶函数(6个)forEach,map,some,every,filter,reduce
es6(3个)find,findIndex,includes
indexOf
Es3
pop()
- 删除数组的最后一位
- 返回被删除的元素
- 会改变原数组
var arr = [11, 22, 33, 44]
console.log(arr) //(4) [11, 22, 33, 44]
var res = arr.pop()
console.log(res) //44
console.log(arr) //(3) [11, 22, 33]
push()
- 往数组的最后位置添加元素(1个或多个)
- 返回数组的新长度
var arr = [11, 22, 33, 44]
console.log(arr) //(4) [11, 22, 33, 44]
var res = arr.push("刘德华", "111")
console.log(res) //6
console.log(arr) // [11, 22, 33, 44, '刘德华', '111']
shift()
- 删除数组的第一位元素
- 返回被删除的元素
var arr = [11, 22, 33, 44]
console.log(arr.shift()) //11
console.log(arr) //(3) [22, 33, 44]
unshift()
- 往数组的第1个位置添加元素(1个或多个)
- 返回数组的新长度
var arr = [11, 22, 33, 44]
console.log(arr.unshift("111", "BBB")) //6
console.log(arr) //(6) ['111', 'BBB', 11, 22, 33, 44]
sort()
- 排序
- 默认是根据ASCII码,进行比较
- a-b 升序
- b-a 降序
var arr = [5, 67, 85, 1, 60, 23]
arr.sort(function (a, b) {
// return a-b //升序
return b - a //降序
})
console.log(arr) //(6) [85, 67, 60, 23, 5, 1]
reverse()
- 倒序
var arr = ["aa", "bb", "cc", "dd"]
console.log(arr.reverse()) //(4) ['dd', 'cc', 'bb', 'aa']
slice()
- 截取
- slice(开始索引,结束索引)
- 包含开始索引,不包含结束索引
- 返回一个新数组,不会影响原数组
- ()里面不写值,表示截取数组中的所有元素
var arr = [11, 22, 33, 44, 55, 66]
//截取数组下标为2和4之间的元素,包含下标为2的元素,不包含下标为4的元素
var res1 = arr.slice(2, 4)
console.log(res1) //(2) [33, 44]
console.log(arr) //(6) [11, 22, 33, 44, 55, 66]
//截取数组下标为2和2之后的所有元素
var res2 = arr.slice(2)
console.log(res2) //(4) [33, 44, 55, 66]
//复制arr数组
var res3 = arr.slice()
console.log(res3) //(6) [11, 22, 33, 44, 55, 66]
splice()
- splice(开始元素,删除元素,"插入元素")
- 会改变原数组,返回一个数组
var arr = [11, 22, 33, 44, 55, 66]
// 2个参数,删除 返回被删除的元素,并且是以数组的方式返回
var res = arr.splice(3, 2)
console.log(res) //(2) [44, 55]
console.log(arr) //(4) [11, 22, 33, 66]
// 3个参数:如果第二参数是0,插入;如果是1或1以上,替换
// 插入
var arr = [11,22,33,44,55,66,77,88]
var res= arr.splice(4,0,'aa',"bb")
console.log(res) //[]
console.log(arr) //(10) [11, 22, 33, 44, 'aa', 'bb', 55, 66, 77, 88]
// 替换
var arr = [11,22,33,44,55,66,77,88]
var res = arr.splice(4,2,"aa","bb")
console.log(res) //(2) [55, 66]
console.log(arr) //[11, 22, 33, 44, 'aa', 'bb', 77, 88]
concat()
- 拼接
- 不会影响原数组,返回一个新数组
var arr1 = [11,22,33]
var arr2 = [44,55,66]
//拼接arr1和arr2
var res = arr1.concat(arr2)
console.log(res) //(6) [11, 22, 33, 44, 55, 66]
//复制数组arr1
var res = arr1.concat()
console.log(res) //(3) [11, 22, 33]
//拼接arr1 + arr1 + "aa" + 33
var res = arr1.concat(arr2,"aa",33)
console.log(res) //(8) [11, 22, 33, 44, 55, 66, 'aa', 33]
join()
- 默认用
,隔开 - 返回一个字符串
var arr = [2020,12,12]
console.log(arr.join()) //2020,12,12
console.log(arr.join("-")) //2020-12-12
console.log(arr.join("/")) //2020/12/12
高阶函数:
item:数组中的元素
index:元素下标
arr:数组
forEach()
- 遍历
- 只能做遍历,没有返回值,不能被中断
- 可以制造异常,结合
try...catch中断
var arr = [11, 22, 33, 44, 55, 66]
arr.forEach(function(item,index,arr){
console.log(item,index,arr)
})
制造异常中断
try {
arr.forEach(function (item, index, aaa) {
console.log(item, index, aaa)
if (index == 1) { //数组下标为1时,中断遍历
throw new Error("制造异常中断")
}
})
} catch (Error) {
}
map()
- 映射
- 有返回值,返回一个新数组,不会改变原数组
- 把数组中的每一个元素做相同的事情
var arr = [1,2,3,4,5]
var res = arr.map(function (item, index, arr) {
return item * 10
})
console.log(res) //(5) [10, 20, 30, 40, 50]
some()
- 一个
- 只要有一个满足条件,就返回true,默认返回false
- 在遍历的过程中,只要条件满足,就中断遍历
var arr = [11, 22, 33, 44, 55, 66]
var res = arr.some(function (item, index, arr) {
return item == 33
})
console.log(res) //true
every()
- 每个
- 所有元素都满足条件,才会返回true,默认返回false
var arr = [11, 22, 33, 44, 55, 66]
var res = arr.every(function (item, index, arr) {
return item > 30
})
console.log(res) //false
var res = arr.every(function (item, index, arr) {
return item > 10
})
console.log(res) //true
filter()
- 过滤
- 只能判断为
false和true,为true时才返回当前元素 - 返回值:找到数组中所有符合条件的元素,并以数组的方式返回
var arr = [11, 22, 33, 44, 55, 66]
var res = arr.filter(function (item, index, arr) {
return item > 30
})
console.log(res) //(4) [33, 44, 55, 66]
reduce()
- 归并
- pre始终为上一次return计算的结果
- 有2个参数
- 第1个参数是回调函数,有4个形参
- pre 上一次回调函数的返回结果或者reduce的初始值
- cur 当前的元素
- index 下标
- arr 原来的数组
- 第2个参数,给第1个pre的初始值
- 第1个参数是回调函数,有4个形参
- 【注】
- 从左往右执行,也就是索引从小到大执行
- 在reduce回调函数中,我们要先给定pre一个值,不然会出现pre取到数组下标为0的元素,cur只能从下标为1开始取值
var arr = [11, 22, 33, 44, 55]
var res = arr.reduce(function (pre, cur, index, arr) {
return pre + cur
},0)
console.log(res) //165
Es6
find()
- 查找
- 通过条件,查找某一项,如果存在就返回这一项
- 只能查找出一个符合条件的值
- 找到了返回该项,没找到返回undefined
var arr = [
{ id: 1, name: "aaa", age: 18 },
{ id: 2, name: "bbb", age: 20 },
{ id: 3, name: "ccc", age: 20 },
{ id: 4, name: "ddd", age: 18 },
]
var res = arr.find(function (item) {
return item.name == "bbb"
})
console.log(res) //{id: 2, name: 'bbb', age: 20}
findIndex()
- 查找
- 返回满足条件的某一项的下标
- 只能查找出一个符合条件的值
- 找到了返回该下标,没找到返回-1
var arr = [
{ id: 1, name: "aaa", age: 18 },
{ id: 2, name: "bbb", age: 20 },
{ id: 3, name: "ccc", age: 20 },
{ id: 4, name: "ddd", age: 18 },
]
var res = arr.findIndex(function (item) {
return item.age == 20
})
console.log(res) //1
includes
- 包含
- 找指定的内容
- 找到了返回true,没有找到返回false
var arr = [11, 22, 33, 44, 55, 22, 11, 99]
console.log(arr.includes(222)) //false
console.log(arr.includes(22)) //true
indexOf()
- 找指定的内容,返回要查询的内容的下标
- 语法:数组 . indexOf ( " 要查找的内容 ",开始查找的元素下标 )
- 开始查找的元素下标默认从0开始,也可以指定开始位置
注:- -1表示没有该内容
- 假若数组中有多个相同的值,返回的结果为查找到的第一个值的索引
var arr = [11, 22, 33, 44, 55, 22, 11, 99]
console.log(arr.indexOf(22)) //1
console.log(arr.indexOf(88)) //-1
console.log(arr.indexOf(22, 2)) //5
排序
冒泡排序
- 口诀:
- 外层循环-1
- 内层循环-1又-i
- 相邻的两个数比较大小
- 问:
1.为什么外循环要-1?
因为两个数只要比较1次,五个数只要比较4次
2.为什么内循环要-1又减- i;
-1防止下标越界,j+1,容易出现下标越界
-i是因为每一轮比较都会出现一个最大数或最小数,这个数字不用再参与比较
3.比较的时候,为什么是j和j+1;
前一个数和后一个数,比较
- 代码:
var arr = [6, 5, 2, 3, 1, 7]
// 2个数,比较1轮,同理6个数,比较5轮
for (var i = 0; i < arr.length - 1; i++) {
// -1防止下标越界 j+1容易出现越界
for (var j = 0; j < arr.length - 1 - i; j++) {
// 前一个数和后一个数比较 ,比较arr[j] 和 arr[j+1]
if (arr[j] > arr[j + 1]) {
var temp = arr[j + 1]
arr[j + 1] = arr[j]
arr[j] = temp
}
}
}
console.log(arr) //(6) [1, 2, 3, 5, 6, 7]
选择排序
- 外层循环-1
- 假定每次下标为i的都为最大(最小)值
- 内层循环:下标为i的元素不用再跟自身进行比较,所以j=i+1
var arr = [6,2,1,4,3,5]
for(var i=0;i<arr.length-1;i++){
//假定每次下标为i的都为最小值
var minIndex = i
//下标为i的元素不用再跟自身进行比较,所以j=i+1
for(var j=i+1;j<arr.length;j++){
//如果遇到比假定数值还小的数,就把下标进行替换
if(arr[minIndex]>arr[j]){
minIndex = j
}
}
//内层for循环结束后,就会得到一个最小值的下标
//判断假定的下标值有没有被修改,
// 没有被修改就继续循环,
// 被修改了就定义一个临时变量进行交换,把最小值赋值给arr[i],然后继续循环
if(minIndex != i){
var temp = arr[i]
arr[i] = arr[minIndex]
arr[minIndex] = temp
}
}
console.log(arr) //(6) [1, 2, 3, 4, 5, 6]
快速排序
- 采用了分治法和利用了递归的原理
var arr = [6,2,1,4,3,5]
//定义一个方法,传入一个数组
function quickSort(list){
// 如果传入的不是数组,就返回一个空数组
if(!Array.isArray(list)){
return []
}
// 如果数组的长度小于2(数组中只有一个数),就返回原数组
if(list.length<2){ //递归的临界值
return list
}
//找出中间下标
//遇到不能整除的要向下取整,使用parseInt或者floor
//不能向上取整,向上取整可能会导致下标越界
var middelIndex = parseInt(list.length/2)
//通过中间下标,得到中间数,并且从原数组中取出来
var middelVal = list.splice(middelIndex,1)
//准备2个空数组,中间数左边和右边的空数组
var left=[],right=[]
for(var i=0;i<list.length;i++){
if(list[i]>middelVal){
//大于中间数的元素,放right数组中
right.push(list[i])
}else{
//小于中间数的元素,放left数组中
left.push(list[i])
}
}
//递归继续拆解left,right数组,拆到数组内的元素都只有1个数,就不拆解了
//最后进行合并,左边的数组 + 中间数 + 右边的数组
return quickSort(left).concat(middelVal,quickSort(right))
}
console.log(quickSort(arr)) //(6) [1, 2, 3, 5, 6, 7]
数组的遍历
- 稀疏数组:数组中有些元素是空的,空的值默认是undefined
- 例:
var arr = ['张三',,,'李四',,'王五','赵六']
for循环
- 通过下标获取值
- 如果遍历稀疏数组时,undefined会被遍历出来
var arr = ['张三','李四','王五','赵六']
for(var i=0;i<arr.length;i++){
console.log(arr[i])
}
for...in
- 通过下标获取值
- 语法:
for(var key in 数组名){} - 如果遍历稀疏数组时,undefined不会被遍历出来
var arr = ['张三','李四','王五','赵六']
for(var key in arr){
console.log(arr[key])
}
for...of
- 直接获取值
- 语法:
for(var value of 数组名){} - 如果遍历稀疏数组时,undefined会被遍历出来
- value直接获取数组元素
var arr = ['张三','李四','王五','赵六']
for(var value of arr){
console.log(value)
}
数组去重方法
利用对象的key值
- 原理:在对象中相同的key值会覆盖
var arr = [1,2,2,4,5,3,1,4,2]
var obj = {}
for(var i=0;i<arr.length;i++){
obj[arr[i]] = "" //使用对象key值相同会被覆盖的原理
}
var arr1 = []
for(var key in obj){
//遍历对象obj,把对象中的key值转为number类型,在push()追加在arr1数组中
arr1.push(Number(key))
}
console.log(arr1) //(5) [1, 2, 3, 4, 5]
利用indexOf === -1
indexOf===-1说明数组中没有这个元素
var arr = [1,2,2,4,5,3,1,4,2]
var arr1 = []
for(var i=0;i<arr.length;i++){
if(arr1.indexOf(arr[i]) === -1){
arr1.push(arr[i])
}
}
console.log(arr) // [1, 2, 2, 4, 5, 3, 1, 4, 2]
console.log(arr1) // [1, 2, 4, 5, 3]
双重for循环
- 会改变原数组
- 【注】:删除之后,数组元素将少一个,所以要j--
var arr = [1,2,2,2,1]
for(var i=0;i<arr.length;i++){
for(var j=i+1;j<arr.length;j++){
if(arr[i] == arr[j]){
arr.splice(j,1)
//删除之后,数组元素将少一个
//为了抵消再次累加后跳过的索引
j--
}
}
}
console.log(arr) //[1,2]
new Set
- ES6中新出的,最简单的数组去重方法
var arr = [1,2,2,4,5,3,1,4,2]
var set1 = new Set(arr)
console.log(set1) //Set(5) {1, 2, 4, 5, 3}
var arr1 = Array.from(set1)
console.log(arr1) //(5) [1, 2, 4, 5, 3]