文章目录
数组
+ 也是 JS 中的一种数据类型 (复杂型数据类型)
+ 一个盒子:存储多个值
=> 但是不是键值对
=> 按照索引进行存储
数组的创建
字面的创建
var arr = []
// 创建一个空数组
// 但是可以直接添加成员
var arr = [1,2,4,5,6] // 使用逗号分隔
内置构造函数的创建
var arr = new Array()
// 不传递参数 是个空数组
// 传递参数
var arr = new Array(100)
// 数组长度为 100 都是空值
// 传递多个参数
var arr = new Array(100,101)
// 成员有两个 100和101
数组的操作
length属性
+ 读 获取数组的长度
var arr = new Array()
arr.length // 返回数组长度
+ 写 设置数组的长度
arr.length = 1 //设置长度为100
索引
+ 按照索引排列
+ 从0开始 依次加1 最后的索引就是 length - 1
+ 索引的读写属性
=> 读: 读取指定索引位置的数据
-> 如果数组这个位置有值,那么返回数据
-> 如果数组这个位置没值,那么返回undefined
var arr = [1,2,3,4,5]
arr[0] // 1
arr[99] // undefined
=> 写: 设置指定索引的数据
-> 如果这个索引有值,那么给这个索引设置
-> 如果这个索引没值,那么就是添加 但是超出length很多 那么用空补齐
var arr = [1,2,3,4,5]
arr[1] = 2
arr[99] = 10
数组的遍历
var arr = new Array(1,2,3,4,5,6)
for(var i in arr){
console.log(i) // 返回下标,成员名称,key
console.log(arr[i]) // 返回数据
}
for(var i = 0;i<arr.length;i++){
console.log(arr[i])
}
arr.name = 'xxx'
arr.age = 18
// 也是可以的 不占用length位置 但是可以用for in 遍历
数组常用方法
+ 就是 js 自带的一些操作数组的方法
+ 使用格式 必须是 数组.xxx()
+ 伪数组不能使用
push
=> 语法: 数组.push(数据1,数据2)
=> 作用: 把所有的参数按照顺序追加到数组末尾的位置
=> 返回值: 追加以后数组的长度
var arr = new Array()
arr.push(1,2,3,4)
console.log(arr) // [1,2,3,4]
pop
=> 语法: 数组.pop()
=> 作用: 删除数组的最后一个数据
=> 返回值: 被删除的数据
=> 直接操作原始数据
var arr = new Array(123,321)
var args = arr.pop()
console.log(args) // 321
console.log(arr) // [123]
unshift
=> 语法: 数组.unshift(数据1,数据2,数据3)
=> 作用: 从数组最前面插入一些数据
=> 返回值: 插入后的数组长度
=> 直接操作原始数据
=> 与push的区别:消耗性能不一样
var arr = [1,2,3]
arr.unshift(0)
arr // [0,1,2,3]
shift
=> 语法: 数组.shift()
=> 作用: 删除数组的第一个数据
=> 返回值: 被删除的数据
=> 直接操作原始数据
reverse反转
=> 语法: 数组.reverse()
=> 作用: 反转数组
=> 返回值: 反转后的数组
=> 直接操作原始数组
sort 排序
=> 语法:
数组.sort() //按照ascii排序 正序
数组.sort(function(a,b){return a-b}) // 按照大小排列 正
数组.sort(function(a,b){return b-a}) // 按照大小排列 反
=> 作用: 排序后的数组
=> 返回值: 排序后的数组
=> 直接操作原始数组
splice 截取数组
=> 语法:
数组.splice(开始索引,多少个.不写默认末尾)
数组.splice(开始索引,多少个,替换数据1,替换数据2,替换数据3....)
=> 作用: 截取数组,替换新内容
=> 返回值: 一定是一个数组
=> 直接操作原始数组
concat合并
=> 语法: 数组.concat(数组1,数组2,...)
=> 作用: 合并数组
如果参数是数组,那么他会把数组拆开,里面的每一个追加到原数组后面
如果参数是数据,直接追加
=> 返回值: 追加好的数组
=> 不改变原始数组
slice
=> 语法:
数组.slice(开始索引,结束索引) // 顾头不顾尾
数组.slice(开始索引,-结束 索引) // 可以写个负数整数
=> 作用: 获取数组里面的某些数据
=> 返回值: 一个数组
=> 不改变原始数组
join
=> 语法: 数组.join('连接符号') // 默认逗号连接
=> 作用: 把数组里面的每一个数据使用连接符号连接在一起
=> 返回值: 是一个连接好的内容.是一个string类型
数组常用方法2
indexOf()
=> 语法:
数组.indexOf(数据)
数组.indexOf(数据,开始索引)
=> 作用: 查询数据的索引
=> 返回值: 如果有数据,那么返回索引,没有返回-1
lastIndexOf()
=> 语法:
数组.lastIndexOf(数据)
数组.lastIndexOf(数据,开始索引)
=> 作用: 反向查看数组里面指定这数据的索引
=> 返回值: 如果有数据,那么返回索引,没有返回-1
forEach()
=> 语法: 数组.forEach(function(item,index,arr){})
item:数组的每一项
index:数组每一项的索引
arr:原始数组
=> 作用: 代替for循环的作用,遍历数组
=> 返回值: 没有
var arr = [1,2,3,4,5,6,7,8]
var res = arr.forEach(function(item,index,arr){
console.log(index,item,arr)
})
map
=> 语法: 数组.map(function(item,index,arr){})
item:数组的每一项
index:数组每一项的索引
arr:原始数组
=> 作用: 映射数组
=> 返回值: 新的数组,里面是对原始数组每一个数据的操作,长度一定和原来的一样
不改变原始数组
var arr = [1,2,3,4,5,6,7,8]
var res = arr.map(function(item,index,arr){
return item * 1.3
})
console.log(res)
map封装底层原理
1.准备一个新的数组
2.遍历原始数组,分别执行函数
3.把每一次函数执行得到的返回值放回原来的数组里面
4.把新的数组当做map的返回值给出来
// 自己实现map
var arr = [1,2,3,4,5,6,7,8]
function myMap(fn){
// fn就是你调用myMap的时候传递的参数
// this指向 谁点的你 这里是arr
var newArr = []
for(var i = 0;i<this.length;i++){
newArr.push(fn(this[i],i,this))
}
return newArr
}
// 需要将mymap加入protorype中
Array.prototype.myMap = myMap
var res = arr.myMap(function(item,index,arr){return item * 3})
fliter 过滤
=> 语法: 数组.fliter(function(item,index,arr){})
=> 作用: 过滤原始数组的数据,把满足的放在新的数组里面
=> 返回值: 新的数组
=> 不改变
arr.filter(function(item,index,arr){return item > 10})
// 伪代码
function myFilter(fn){
var newArr = []
for(var i = 0;i<this.length;i++){
if (fn(this[i],i,this)){
newArr.push(this[i])
}
}
return newArr
}
Array.prototype.myFilter = myFilter
var res = arr.myFilter(function(item,index,arr){return item < 20})
console.log(res)
every 每一个满足
=> 语法: 数组.every(function(item,index,arr){})
=> 作用: 判断原始数组里面是不是每一个都满足条件
=> 返回值: 是一个布尔值
如果原始数组中每一个都满足,那么 true
只要有一个不满足 就返回 false
arr.every(function(item,index,arr){return item > 0}) // true
底层原理
1.假设一个变量为 true 表示所有数据都满足条件
2.循环遍历数组
执行传递进来的函数
如果函数返回的实 true 那么循环继续
如果函数返回的是 false 那么 把假设 true 改为 false 结束循环
some 有一个满足
=> 语法: 数组.some(function(item,index,arr){})
=> 作用: 判断数组中是否有一个满足条件
=> 返回值: 是一个布尔值
如果原始数组有一个满足,那么 true
都不满足 就返回 false
数组常用方法3
Es2015(es6) 以后 标准浏览器, ie10以上
copyWithin()
=> 语法: 数组.copyWithin(目标位置,开始索引,结束索引)
目标索引:当你替换内容的时候,从哪一位索引位置开始
开始索引:数组哪一个索引位置开始单做替换内容
结束索引: 数组哪一个索引位置结束单做替换内容
=> 作用: 使用数组里面的内容 替换 里面的内容
fill 填充
=> 语法: 数组.fill(填充的数据,开始索引,结束索引)
要填充的数据:你想用什么数据填充数组里的每一位
开始索引:从哪一位索引开始填充,默认是0
结束索引:填充到哪一个索引位置,默认值是 末尾
前提:数组要有length
=> 作用: 使用指定数据填充数组
=> 返回值: 填充好的数组
includes
=> 语法: 数组.includes(数据)
=> 作用: 查看数组中是否有个数据
=> 返回值: 是一个布尔值
有就是,true
没有就是,false
flat
=> 语法: 数组.flat(数字)
数字还可以填:infinity 无穷
=> 作用: 拍平数组
=> 返回值: 拍平以后的数组
flatMap
=> 语法: 数组.flatMap(function(item,index,arr){})
=> 作用: 拍平数组但是只能拍一层 一遍拍平 一遍映射
=> 返回值: 拍平以后的数组
find 查找
=> 语法: 数组.find(function(item){})
=> 作用: 根据条件找到数据
=> 返回值: 找到的数据
findindex
=> 语法: 数组.findindex(function(item){})
=> 作用: 根据条件找到数组里面满足条件的数据的索引
=> 返回值: 找到的索引
算法
把一个乱序的数组 按照一定的算法结构排序好
冒泡排序
双层for循环,一层减一次
里层减外层,变量相交换
// 冒泡排序
var arr = [1,5,2,7,4,8,3,9,0]
/*
拿到第一个 判断是否比第二个大 大了交换位置
然后比较第三个 大了交换位置 依次类推
*/
// 外循环 控制循环的次数 最多交换 arr的长度-1
for(var i = 0; i<=arr.length-1;i++){
// 内循环控制 每一次 需要对比的次数 也是9次
for(var j = 0;j<=arr.length-1;j++){
// 判断索引是否大于
var a = arr[j]
var b = arr[j+1]
if(a>b){
arr[j] = b
arr[j+1] = a
}
}
}
// 优化
for(var i = arr.length-1; i>0;i--){
for(var j = 0;j<=i-1;j++){
var a = arr[j]
var b = arr[j+1]
if(a>b){
arr[j] = b
arr[j+1] = a
}
}
}
// 优化2
for(var i = 0; i<=arr.length-1;i++){
for(var j = 0;j<=arr.length-1-i;j++){
if(arr[j]>arr[j+1]){
var tmp = arr[j]
arr[j] = arr[j+1]
arr[j+1] = tmp
}
}
}
计数排序
// 计数排序
/*
1.准备一个空数组
2.遍历原始数组
3.把原始数组里面的每一个数字单做索引填充到新的数组里面
没有数据 设1 有数据++
4.把临时素组返回原始数组
*/
var arr = [1,5,2,7,4,8,8,3,3,9,0,44,99,20,34,444,64]
var arr2 = []
for(var i = 0;i<arr.length;i++){
if(arr2[arr[i]] !== undefined){
arr2[arr[i]] ++
}else{
arr2[arr[i]] = 1
}
}
console.log(arr2)
arr.length = 0
for(var i = 0;i<arr2.length;i++){
// 判断当前这个是不是undefined
if(arr2[i] !== undefined){
// i 就是值,值就是他的个数
for(var j = 1;j<=arr2[i];j++){
arr[arr.length] = i
}
}
}
console.log(arr)