1.概述
(1)数组是什么 :使用单独的变量名来存储一系列的值。
(2)数组可以干什么?存放内容
2.三种创建方法:
① 构造函数的形式:new Array()
② 字面量的形式:[]
序列为参数,如1,2,3 ;值的类型任意,如【{},{},“12里”,3】
③ API形式
from({length},箭头函数)
const grid=Array.from({length:row},()=>new Array(col).fill(val))
3.数组中的属性 :length
4.数组中的方法
splice : 移接
splite :分裂(数组没有这个方法)
shift:去污、转移
(1)合并数组:crr=arr.concat(brr) 返回多数组的元素组成的新数组
(2)合并为字符串:str=arr.join(‘连接符’) 返回 元素中间用连接符连接的字符串;
[1,2] =>”1连接符2”
(3)删:删头 item=arr.shift() , 删尾 item=arr.pop() 返回值:被删的元素值
(4)增:头增 l=arr.unshift(1,2) ,尾增 l=arr,push(1,2) 返回值:插入后的新长度
(5)增删: delArr=arr.splice(delStart,end,[item1 , i2])
- 删除指定下标: splice(idx,0)
- 在指定位置添加序列:splice(idx,1,实参序列)
- 返回值:被删元素数组,无删则为空数组
(6)截取:brr=arr.slice(start,end) 截取数组的指定部分,含start不含end
(7)逆序:brr=arr.reverse() 逆转数组中元素的顺序。 || 可以用来翻转字符串
(8)排序:brr=arr.sort() 按元素首位对数组的元素进行排序|归类
[2,3,4,1,42,11,5]=>[1,11,2,3,4,42,5]
升序: arr.sort((a,b)=>a-b);
遍历:
for(var i=0;i<arr.length;i++){}
for ( var item of arr) .forEach( f(item,index)=>{ //this==window} )
(9)各方法的时间复杂度
- pop(),push()等在数组尾部操作的方法的时间复杂度为O(1)
- forEach()、map()、shift()、unshift()、等需要遍历或者在数组头部操作的方法的时间复杂度为O(n)
- splice()、concat()、find()等方法的时间时间复杂度为O(n),但最优情况可能为O(1),如splice()在数组尾部操作
5.函数式编程
forEach || some 用item do what ;
filter 选出合条件的item,组成新数组,返回;
map修改每个item,并返回新数组;
reduce 累计item,返回累计计算结果;
find 返回第1个合法item的值, findIndex 返回第1个合法item 的下标;
(1)ForEach 、some
- 和some 的区别: forEach一定会遍历整个数组,some中返回true则中断遍历;
- 是什么:调用数组的每个元素,并将元素传递给回调函数,用这个元素执行一些操作。
- 语法:
array.forEach( function(currentValue, index, arr){
对每个数组元素都执行的操作,不改变原数组
}, thisValue)
- 解释:
arr.forEach( 回调函数(当前元素[,其下标,其所属对象]){ do what by item} [,thisValue]) - 源码示例:
var arr=['A','B','c'];
function forEach(arr,fn){
for(var i=0;i<arr.length;i++){
fn(arr[i]);
}
}
forEach(arr,function(value){
console.log(value+0)
})
(2)filter
-
返回符合条件的元素组成的数组 (不修改原数组)
-
是什么:创建一个新的数组,该数组包含了所有符合条件的元素,返回该数组。
-
语法:array.filter(function(currentValue[,index,arr]){ return判断语句}[,
thisValue]) 源码 -
示例:
var arr=['A','B','c','A','A'];
function filter(arr,fn){
var br=[];
for(var i=0;i<arr.length;i++){
if( fn(arr[i]) ){
br.push(arr[i])
}
}
return br;
}
console.log(
filter(arr,function(value){
return value=='A';
})
)
- 使用示例:
var arr=['A','B','c','A','A'];
console.log(
arr.filter(function(value){
return value=='A'; //必须返回判断条件
})
)
Note : forEach是使用数组的元素do what,filter是返回符合条件的元素组成的数组;前无返回,后必返回条件判断语句
(3)规约函数:Reduce
- 通过一个函数调用另一个函数,将数组转换为单一的值
- 是什么:reduce接收函数作为累加器,按照累加器的要求将数组中的all元素最终计算为一个值并返回。
- 语法:
array.reduce( function(total, currentValue[, currentIndex, arr]){} [, initialValue ] )
回调函数(初始值,当前元素) { return 计算值}
- 源码示例:
function reduce(fn,num,arr){
arr.forEach(function(value){
num=fn(num,value)
})
return num;
}
function add(n1,n2){
return n1+n2;
}
console.log(
reduce(add,0,[1,2,3,4,5])
)
- 使用示例:
var arr=[1,2,3,4,5];
console.log(
arr.reduce(function(num,val){
return num+val
},0,)
)
- 简化
var arr=[1,2,3,4,5];
console.log(
arr.reduce((target,item)=>target+item,0)
)
(4)映射函数:Map
- 是什么:遍历数组,对数组的每个元素执行某些操作后,将操作结果存入新数组并返回。
- 语法
array.map( function(currentValue,index,arr){ return 计算结果}, thisValue)
- 源码示例:
function map(fn,arr){
var brr=[];
arr.forEach(function(value){
brr.push(fn(value))
})
return brr;
}
console.log(
map(Math.round,[1.2,32.1,2.5,6.8,9.4])
) // [1, 32, 3, 7, 9]
- 使用示例:
var arr=[1.2,32.1,2.5,6.8,9.4];
console.log(
arr.map(Math.round)
)
6.扩展运算符(…) es6
spread:v n 伸展、传播
let [a,,b,...c]=[1,2,3,4,5,6,7];
console.log(a); //1
console.log(b); //3
console.log(c); //[4,5,6,7]
7.es6新增方法
扩展运算符
Array.from() 、Array.of() 、数组的空位 Array(3)
数组实例的:
fill() 、 includes() 、find() 和 findIndex()、copyWithin()
entries(),keys() 和 values()
flat(),flatMap()
Array.prototype.sort() 的排序稳定性
(1)Array.from() : 把一个看起来类似于数组的对象,转换成真正的数组
例如用getElementByTagName获取的数组,实际上不是一个数组,因为它没有push等方法
let span=document.getElementsByTagName('span');
let spanArr=Array.from(span); //转换后由push方法
console.log(spanArr.push(1)); //3 返回item在数组中的index
console.log(span.push(1)); //span.push is not a function
(2)Array.of() : 把序列,转换为数组
console.log(Array.of(1,2,3,4,5,'a')); //[1, 2, 3, 4, 5, "a"]
(3)copyWithin(target,start,end) : 将指定位置的成员覆盖到其他位置的成员,最后返回新的数组,改变原数组
- 参数1》target :从该位置开始替换数据。
- 参数2》start :从该位置开始读取数据,默认为 0。如果为负值,表示倒数。
- 参数3》end :到该位置前停止读取数据,默认等于数组长度。如果为负值,表示倒数。
let arr=[0,1,2,3,4,5,6,7];
console.log(arr.copyWithin(0,3,4)); // [3, 1, 2, 3, 4, 5, 6, 7]
console.log(arr) // [3, 1, 2, 3, 4, 5, 6, 7]
(4)find() findIndex() //实参都是回调函数
let arr=[1,2,3,4,5,6,7];
console.log(arr.find( item=>item>3)); //4 返回第一个符合条件的item的值
console.log(arr.findIndex( item=>item>3)); //3 返回第一个符合条件的item的index
(5)填充 fill(‘替换成什么’,从哪里开始替换index,在哪里结束) : 填充数组 ,默认值(‘’, 0, arr.length) ;
let arr=[1,2,3,4,5,6,7];
console.log(arr.fill('r',2,4)); //[1, 2, "r", "r", 5, 6, 7]
(6)entries(),keys() 和 values() 方法
let arr=[1,2,3,4,5,6,7];
for(let k of arr.keys()){ //数组的key就是数组中item的下标
console.log(k); //0 ,1 ,2....
}
for(let k of arr.values()){
console.log(k);
}
for(let [k,v] of arr.entries()){ //entries返回数组 【key,value】
console.log(k,v);
}
(7)includes() : 返回的是布尔值
indexOf返回下标,无则返回-1;数组没有startsWith 和endsWith方法
arr.includes(item)
8.排序
(1)冒泡排序
- 解题思路:遍历,每次当前元素与相邻的元素进行比较,大于则交换两个元素,每一趟遍历都会将新序列的最大值放在最终位置
- 时间复杂度:嵌套遍历,O(n**2)
- 空间复杂度:常量级
function bubblingSort (nums) {
for (let i = 0;i < nums.length;i++) {
for (let j = 0;j < nums.length - i - 1;j++) {
if (nums[j] > nums[j + 1]) {
const temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
}
return nums;
}
(2)快速排序 (Chrome)
- 解题思路:取一个基数,大于基数的放右边,小于的放左边,依次递归返回结果值;
- 时间复杂度:每个item遍历1次,且每次递归左右子数组,由于递归的时间复杂度=树的高度,每次递归都是原length>>1,故n2logn=nlogn
function quickSort (nums) {
if (nums.length < 2) return nums;
const standard = nums[0], left = [], right = [];
for (let i = 1;i < nums.length;i++) {
if (nums[i] < standard) { left.push(nums[i]) }
else {
right.push(nums[i])
}
}
return [...quickSort(left), standard, ...quickSort(right)]
}
(3)归并排序(Firefox)
- 解题思路:分,取mid,将原数组分为2个部分;合,遍历返回的两个正序数组,比较大小进行合并;
- 时间复杂度:
- 分的时间复杂度logN
- 合的时间复杂度n
- 分合嵌套:总时间复杂度为nlogN
function mergerSort (nums) {
// 终点
if (nums.length <= 1) return nums;
// 分
const mid = Math.floor(nums.length / 2);
const left = mergerSort(nums.slice(0, mid))
const right = mergerSort(nums.slice(mid))
// 合
const res = [];
while (left.length || right.length) {
if (left.length && right.length) {
res.push(left[0] < right[0] ? left.shift() : right.shift())
} else if (left.length) {
res.push(...left)
break;
} else {
res.push(...right)
break;
}
}
return res;
}