数组
数组的使用方法:
- 四个维度:
- 方法的定义
- 方法的参数
- 方法的返回值
- 原有数组是否会发生改变
数组的增删改(原数组都会改变)
- push
- 方法的定义:向数组末尾增加内容(数组也会直接进到数组后)
- 方法的参数:传递多个值
- 方法的返回值:新数组的length
- 原有数组是否会发生改变:是
//向数组末尾增加内容:push方法(可以增加多项)
let ary = [12,23,34];
console.log(ary.push(12)) // 4
console.log(ary) // [12,23,34,12]
//------------------------------------------------
ary[ary.length] = 'xxx'; // 只能在末尾增加一项
//------------------------------------------------
ary = [...ary,'xxx'] // 可以增加多项,但是数组地址发生了改变
- unshift
- 方法的定义:向数组开头增加内容
- 方法的参数:传递多个值
- 方法的返回值:新数组的length
- 原有数组是否会发生改变:是
let ary =[12,23,45]
console.log(ary.unshift(23,34))//5
console.log(ary)
// ary[-1]='xxx'//不行
// console.log(ary)
ary =[23,34,...ary]
console.log(ary)
- pop
- 方法的定义:向数组末尾删除一项
- 方法的参数:无
- 方法的返回值:删除的那一项
- 原有数组是否会发生改变:是
//pop方法只能删除最后一项
let ary = [12, 23, 34];
console.log(ary.pop())//34
console.log(ary)//[12, 23]
ary.length-- //删除数组末尾一项
ary.length -= 2; //删除数组末尾两项
ary.length = 0; //删除数组
console.log(ary)
- shift
- 方法的定义:向数组开头删除一项
- 方法的参数:无
- 方法的返回值:删除的那一项
- 原有数组是否会发生改变:是
let ary = [12, 23, 45];
// console.log(ary.shift()); //12
// console.log(ary); //[23, 45]
- splice
- 方法的定义:实现数组的增删改
- 方法的参数:不定
- 方法的返回值:是一个新的数组,数组里面存储的是删除的内容
- 原有数组是否会发生改变:是
- (n): 如果只传一个参数,那就是从索引n开始,删除到末尾
- (n,m):从索引n开始,删除m个
- (n,m,x):从索引n开始,删除m个,用x替换
- (n,0,x):从索引n开始,删除0个,把x放到索引n对应值的前面
(n,m):从索引n开始,删除m个
(n): 如果只传一个参数,那就是从索引n开始,删除到末尾
let ary = [12, 23, 45, 'erya'];
console.log(ary.splice(1,2));//[23, 45]
console.log(ary.splice(ary.length-1,1));//删除数组的最后一项 ["erya"]
console.log(ary.splice(0));//清空数组 ,从索引0开始,删除到末尾
console.log(ary.splice());//[] 啥也不干
console.log(ary.splice(3,0));// 一个也不删
console.log(ary);//[12, "erya"]
//(n,m,x):从索引n开始,删除m个,用x替换
let ary = [12,34,56,78];
console.log(ary.splice(1,2,333)) // [34,56]
console.log(ary) // [12,333,78];
//(n,0,x):从索引n开始,删除0个,把x放到索引n对应值的前面
console.log(ary.splice(0,0,111)) // []
console.log(ary) // [111,12,34,56,78];
//向数组最后一项增加一项----------------------------------
console.log(ary.splice(ary.length,0,999)) // []
console.log(ary) // [12,34,56,78,999]
数组的删除增加
//删除数组末尾最后一项:
ary.length--
pop
splice(ary.length-1)
//向数组开头删除一项:---------------------------------------
shift
splice(0,1)
//向数组开头增加--------------------------------------------
unshift
splice(0,0,x)
[x,...ary]
//数组末尾增加----------------------------------------------
push
ary[ary.length] = 'xxx'
splice(ary.length,0,x)
[...ary,x]
数组的截取(查询)和拼接:(原数组不会改变)
- slice
- 方法的定义:实现数组的截取(查询)
- 方法的参数:不定
- 方法的返回值:是一个新的数组,数组里面存储的是截取的内容
- 原有数组是否会发生改变:否
- (n,m)从索引n开始,截取到索引m(索引m对应的值不算)
//(n,m)从索引n开始,截取到索引m(索引m对应的值不算)
let ary = [12,34,56,78,'a','b']
console.log(ary.slice(0,1)) // [12]
console.log(ary) // [12,34,56,78,'a','b']
//克隆数组------------------------------------------------
console.log(ary.slice(0,ary.length)) // [12,34,56,78,'a','b']
console.log(ary.slice(0)) // [12,34,56,78,'a','b']
- concat
- 方法的定义:实现数组的拼接(拼接把俩数组拼接起来形成一个数组)
- 方法的参数:可以是多个值
- 方法的返回值:是一个拼接后的新数组
- 原有数组是否会发生改变:否
let ary = [12,34,56,78]
console.log(ary.concat([11,22],[33],ture)) // [12,34,56,78,11,22,33,true]
//克隆数组------------------------------------------------
console.log(ary.concat()) // [12,34,56,78]
数组的排序:
- reverse
- 方法的定义:实现数组的倒叙
- 方法的参数:无
- 方法的返回值:排序之后的数组
- 原有数组是否发生改变:是
let ary = [12,23,45,67,13];
console.log(ary.reverse()); // []
console.log(ary)
- sort(排序)
- 方法的定义:实现数组的排序
- 方法的参数:无,可以传一个函数
- 方法的返回值:排序之后的数组
- 原有数组是否发生改变:是
- 如果不传参,只能排列一位数的数组(按照左边第一位从小到大排列)
// 如果不传参,只能排列一位数的数组(按照左边第一位从小到大排列)
let ary = [5,2,1,3,5];
console.log(ary.sort())
console.log(ary)
let ary =[29,31,114,9,20];
console.log(ary.sort())
//传一个函数-------------------------------------------------------------
console.log(ary.sort( (a,b)=>{
// 如果a-b那就是从小到大排列,反之(b-a)就是从大到小排列
return a-b
} ))
检测数组中是否包含某一项
- indexOf和lastIndexOf
- 方法的定义:检测数组中是否包含某一项
- 方法的参数:检测的那一项
- 方法的返回值:如果检测是有,那就是有这一项的索引,如果没有就是-1
- 原有数组是否发生改变:否
//indexOf是找检测的是第一项的位置
//(n,m):n是被检测的值,m是开始检测的位置
let ary = [12, 23, 45, 23, 45, 36]
console.log(ary.indexOf(23,2));//3
console.log(ary.indexOf(23));//1
console.log(ary.indexOf(89));//-1
console.log(ary.indexOf());//不传参没有找到处理 -1
//lastIndexOf:是找的检测的值最后一次出现的位置
//(n):1检测到末尾
//(n,m):n是被检测的值,m是检测结束的位置
console.log(ary.lastIndexOf(23));//3
console.log(ary.lastIndexOf(23,2));//1 */
- includes
- 方法的定义:检测数组中是否包含某一项
- 方法的参数:检测的值
- 方法的返回值:有返回true,没有返回false
- 原有数组是否发生改变:否
let ary = [12, 23, 45, 23, 45, 36];
console.log(ary.includes(83));//false
console.log(ary.includes(12));//true
console.log(ary.includes());// 不传参按没有找到处理 false */
数组转字符串
- toString()
- join:
- 方法的定义:把数组以特定的分隔符换为字符串
- 方法的参数:字符串格式的分隔符
- 方法的返回值:转换后的字符串
- 原数组是否发生改变:否
let ary = [12, 23, 45, 67, 34]
console.log(ary.join()); //'12,23,45,67,34' 如果不传值分割符就是逗号
console.log(ary.join(' ')); //'12 23 45 67 34' 空字符串
console.log(ary.join('$')); //'12$23$45$67$34' 如果不传值分割符就是逗号
console.log(ary);
遍历数组
- forEach
- 方法的含义:遍历数组
- 方法的参数:函数
- 方法的返回值:无
- 原数组是否发生改变:否
let ary =[1,true,2,NaN,3];
ary.forEach((item, index)=>{
// item是数组的每一项
// index是每一项的索引
// 有多少项就循环多少轮
console.log(item, index)
})
let fn = (...arg)=>{
let total = null;
arg.forEach((item,index)=>{
if(!isNaN(Number(item))){
total+=item
}
})
return total
}
console.log(fn(...ary))
- map:
- 方法的含义:遍历数组
- 方法的参数:函数
- 方法的返回值:改变后的新数组
- 原数组是否发生改变:否
// ``:反引号(模板字符串)${}里可以识别变量
// let ary =[1,2,3,4,5]
//修改数组的值
let num = ary.map((item, index) => {
// item是数组的每一项
// index是每一项的索引
// 数组有多少项就循环多少次
return `我是第${item}个li`
})
// console.log(num)
// console.log(ary)
数组去重
- 数组去重的第一种方式
let ary = [12,23,34,12,23];
function fn(ary){
let newAry = []
for(var i = 0;i<ary.length;i++){
let item = ary[i]
if(!newAry.includs(item)){
newAry.push(item);
}
}
return newAry
}
- 数组去重第二种方法:双for循环
/*
1、循环数组的每一项
2、拿当前项和后面的数依次做比较,如果后面的数和当前项相等了,那就在原数组里删除相等的数(splice)
*/
let ary = [1, 2, 9, 1, 2, 5, 1, 2, 3];
let fn = (ary) => {
// 循环数组每一项
for (var i = 0; i < ary.length; i++) {
let item = ary[i] // 数组的每一项 1
// console.log(item)
// 外面大循环每循环一次,这个小循环就会从头到尾循环一遍
for (var j = i + 1; j < ary.length; j++) {
let cur = ary[j] // 当前项后面的每一项
// console.log(cur)
// 如果当前项和后面的某一项相等了,条件成立
if (item === cur) {
ary.splice(j, 1); // 从原数组中删除重复的那一项
j--; //为了防止数组塌陷,删除之后要把j--从数组中删除一项,后面的每一项的索引都得往前挪一位(数组塌陷)
}
}
return ary
}
}
console.log(fn(ary))
console.log(ary)
- 数组去重第三种方法:利用对象的属性名存在不是undefined属性
let ary = [1, 1, 2, 3, 1, 2, 3];
// 循环数组的每一项,然后把数组的每一项都放进对象里(让键值对的key和value都等于那一项)
function fn(ary) {
let newObj = {} // 创建一个新对象用来存储键值对
// 循环数组的每一项
for (var i = 0; i < ary.length; i++) {
// 检测一下当前项在对象里有没有,如果有,那以下条件就成立
// 也就是说以前就存储过这一项(证明已经是重复项)
if (newObj[ary[i]] !== undefined) {
//ary.splice(i,1);// 删除重复项
//i--; // 防止数组塌陷
ary[i] = ary[ary.length - 1]; //用数组的最后一项替换重复的那一项
ary.length--; // 删除数组最后一项
i--; // 把替换的值还要检测一遍
// continue;
} else {
// 如果对象中没有这个属性名对应的属性值,那就新增这个键值对
newObj[ary[i]] = ary[i]
}
}
// console.log(newObj)
}
fn(ary)
console.log(ary)
数组排序
冒泡排序法
// 冒泡排序:
// 原理:数组的每一项进行两两比较,如果前一项大于后一项就交换位置
// let ary = [12,23,11,34,10,9];
/*
第一轮比较(比较了5次-已经执行过的轮数)
12,23 [12,23,11,34,10,9]
23,11 [12,11,23,34,10,9]
23,34 [12,11,23,34,10,9]
34,10 [12,11,23,10,34,9]
34,9 [12,11,23,10,9,34]
第二轮(比较4次 ary.length-1-已经执行过的轮数)
12,11 [11,12,23,10,9,34]
12,23 [11,12,23,10,9,34]
23,10 [11,12,10,23,9,34]
23,9 [11,12,10,9,23,34]
第三轮(比较3次)
*/
// 每比较一轮就会产生一个最大值,当前数组一共六个值,比较五轮就会产生5个最大值,剩下的那个肯定是最小的(ary.length-1)
// 每轮比较的次数 (ary.length-1已经执行过的轮数)因为每次比较一轮就会产生一个最大值,最大值不需要参与比较
// let temp = null;
// let a = 12;
// let b = 13;
// temp = a; // 12
// a = b // 13
// b = temp // 12
let ary = [12, 23, 11, 34, 10, 9];
function bubble(ary) {
// 控制的比较的轮数
for (var i = 0; i < ary.length - 1; i++) {
// 控制的是每一轮比较的次数
for (var j = 0; j < ary.length - 1 - i; j++) {
// 如果前一项大于后一项就两两交换位置
if (ary[j] > ary[j + 1]) {
let temp = ary[j];
ary[j] = ary[j + 1];
ary[j + 1] = temp;
}
}
}
return ary
}
console.log(bubble(ary))
插入排序法:
let ary = [12, 23, 45, 11, 10, 23];
function insert(ary) {
let handAry = []; // 用来存放手里的牌
handAry.push(ary[0]); // 抓了第一张牌
// 这个循环就是抓牌
for (var i = 1; i < ary.length; i++) {
let item = ary[i] // 抓的每一张牌
// 控制的是跟我手里的每一张牌去做比较(从右往左比较)
for (var j = handAry.length - 1; j >= 0; j--) {
let cur = handAry[j] // 手里的每一张牌
// 如果抓的牌比手里的牌大了,就插入到这张牌的后面,并且停止比较
if (item > cur) {
handAry.splice(j + 1, 0, item);
break;
}
// 如果能运行到这,证明抓的这张牌比我手里的牌都小,就直接放到数组的最前面
if (j === 0) {
handAry.unshift(item);
}
}
}
return handAry
}
快速排序
- 递归
- 递归:就是函数自己调用自己,直到满足某些条件就停止递归
// 实现1到5之间的偶数的和
function sum(num) {
if (num > 5) {
return 0
}
if (num % 2 === 0) {
return num + sum(num + 1)
}
return sum(num + 1)
}
console.log(sum(1)) // 6
// function sum(1){
// return sum(1+1) // 6
// }
// function sum(2){
// return 2 + sum(2+1) // 4
// }
// function sum(3){
// return sum(3+1) // 4
// }
// function sum(4){
// return 4 + sum(4+1) // 0
// }
// function sum(5){
// return sum(5+1) // 0
// }
// function sum(6){
// return 0
// }
- 快速排序
let ary = [3, 4, 2, 1];
function quick(ary) {
// 4、如果数组中的length小于等于1,那就结束递归,把原数组return出去
if (ary.length <= 1) {
return ary
}
// 1、获取中间的一项作为基准(并且把原数组中的那一项删除)
let middleIndex = Math.floor(ary.length / 2) // 拿到中间项的索引
let middleValue = ary.splice(middleIndex, 1)[0];
// 2、创建两个数组,循环数组的每一项和基准做比较,如果每一项小于基准,就放到左边数组,反之放右边
let leftAry = [];
let rightAry = [];
for (var i = 0; i < ary.length; i++) {
if (ary[i] < middleValue) {
leftAry.push(ary[i])
} else {
rightAry.push(ary[i])
}
}
// 3、不断重复1和2步骤(递归)
return quick(leftAry).concat(middleValue, quick(rightAry))
}
console.log(quick(ary))
// return [1].concat(2, [3,4])
// return [1] return [3].concat(4, [])
// return [3] return []
数组的相关方法
- filter 过滤 找不到返回[]
- find 从左到右循环,直到找到满足条件的那一项,把这项返回;如果没有找到,那么返回undefined;
- every 找到第一个返回false的值;就不再向后继续查找;返回一个布尔值;
- some 找到返回true的第一项,找到立即停止;不再向下循环;如果没有符合条件的,返回false;
- reduce 收敛 用于求和
//filter 过滤 找不到返回[]
如果回调函数返回true,就把这一项放到新数组中返回;不改变原数组;
let newAry = ary.filter(function (item) {
// console.log(item);
return item > 10
})
console.log(newAry);
//find 从左到右循环,直到找到满足条件的那一项,把这项返回;如果没有找到,那么返回undefined;
找true 返回 那一项
let newAry = ary.find(function (item) {
// console.log(item);
console.log(item);
return item > 100
})
console.log(newAry);
find 找到第一个符合条件的
//every 找到第一个返回false的值;就不再向后继续查找;返回一个布尔值;
如果所有的成员的回调都返回true,这个结果就是true
找false 返回 布尔值
let newAry = ary.every(function (item) {
// console.log(item);
console.log(item);
return item > 0
})
console.log(newAry);
//some 都不满足是 false 有一个满足就是true,就停止
let newAry = ary.some(function (item) {
// console.log(item);
console.log(item);
return item >5
})
console.log(newAry);
let arr = [12,3,45,89,778,100]
// some : 找到返回true的第一项,找到立即停止;不再向下循环;如果没有符合条件的,返回false;
// 找true every :false;
let s = arr.some(function(item,index){
console.log(item);
return item>999;
});
console.log(s);
//reduce 收敛 用于求和
let newAry = ary.reduce(function (prev,next) { //第一项,第二项
console.log(prev,next);
//prev 上一次回调函数的返回值
return prev+next
},0)//第一项变成了reduce的第二个参
console.log(newAry);
数组扁平化
//编写一个方法“flatten”,将数组扁平化
let ary = [1, 2, 3, [1, 2, 3],
[1, 2, 1, 6]
]
//1
let c = ary.flat(Infinity);
console.log(c);
//2
let d = ary.toString().split(",").map(item => parseFloat(item))
console.log(d);
//3
let e = JSON.stringify(ary).replace(/\[|\]/g, "").split(",").map(item => parseFloat(item))
console.log(e);
//4
console.log(ary.join(",")); //1,2,3,1,2,3,1,2,1,6
let f = ary.join(",").split(",").map(item => parseFloat(item))
console.log(f);
//5
//console.log(ary);
while (ary.some(item => Array.isArray(item))) {
ary = [].concat(...ary)
}
console.log(ary);
//6循环
function flat(arr) {
let a = [];
arr.map(item => {
if (item instanceof Array) {
flat(arr)
} else {
a.push(item)
}
})
return a
}
console.log(flat(ary));
//
// let a = [];
// function fn(arr) {
// if (Object.prototype.toString.call(arr) === "[object Array]") {
// arr.forEach((item, index) => {
// fn(item)
// })
// } else {
// a.push(arr)
// }
// }
// fn(arr)
// console.log(a);