1.数组常用方法
方法的作用和含义
方法的实参(类型和含义
方法的返回值
原来数组时候会发生改变
- 实现数组增删改的方法(都会修改原来的数组)
push : 向数组末尾添加内容
@params
多个任意类型
@return
新增数组的长度
let ary = [10, 20];
let res = ary.push(30, 'AA'); //数组方法向后添加
ary[ary.length] = '100' //原生js向数组后添加
console.log(res, ary);
unshift : 向数组开头位置添加内容
let ary = [10, 20];
let res = ary.unshift(30, 'AA'); //数组方法向后添加
console.log(res, ary); //30,AA,10,20
shift : 删除数组第一项
let ary = [10, 20, 30, 40];
let res = ary.shift(); //数组方法向后添加
console.log(res, ary); //20,30,40
// 基于原生js中的delete 把数组当成普通的对象,确实可以删除某一项内容,但是length不会修改长度,真实项目中杜绝删除的使用
pop : 删除数组最后一项
let ary = [10, 20, 30, 40];
let res = ary.pop(); //数组方法向后添加
console.log(res, ary); //10,20,30
ary.length--;
console.log(ary); //10,20 基于原生js把数组长度减一,默认就是删除最后一项
// 基于原生js中的delete 把数组当成普通的对象,确实可以删除某一项内容,但是length不会修改长度,真实项目中杜绝删除的使用
splice : 实现数组增加删除修改
@n,m x都是数字,从索引n开始删除m个元素,用x占用原来删除的部分
n,0,x 从索引n开始,一个都不删吗,把x放到x索引n的前面
@return 把删除的部分用新数组存储起来返回
let ary = [10, 20, 30, 40, 50, 60, 70, 80];
// let res = ary.splice(2, 4)
// console.log(res, ary); //4. 10,20,70,80
// res = ary.splice(0);
// console.log(ary, res); //清空一个数组,把原始数组的内容以新数组存储起来,
// 删除最后一项 和第一项
ary.splice(ary.length - 1);
ary.splice(0, 1);
console.log(ary); //20,30,40,50,60,70
let ary = [10, 20, 30, 40, 50, 60]
let res = ary.splice(1, 2, '珠峰');
console.log(res, ary); //10 ,珠峰,40,50,60
ary.splice(3, 0, '呵呵呵');
console.log(ary); //10,珠峰,40,呵呵,50,60
ary.splice(ary.length, 0, 'aaaa');
console.log(ary); //10,珠峰,40,呵呵,50,60,aaa
ary.splice(0, 0, '0000');
console.log(ary);//'000',10,珠峰,40,呵呵,50,60,aaa
2.数组的查询
此组方法,原数组不会发生改变
slice : 实现数组的查询
@params:n,m,都是从数字开始,从索引n开始,找到索引为m的地方(不包含m项)
@return 把找到的内容一个新的数组的形式返回
let ary = [10, 20, 30, 40, 50];
let res = ary.slice(1, 3);
console.log(res); //20,30
// 如果不写m,则直接从n开始查询到最后一项
let res1 = ary.slice(2);
console.log(res1); //30,40,50
// 数组克隆
res = ary.slice(0);
console.log(res); //10,20,30,40,50
思考:如果n/m为负数会如何,如果n大于m会如何,如果是小数会如何,如果是非有效数字会如何,如果m或者n的值比最大索引大,会如何,2,这张克隆方式为浅克隆,预先深克隆如何处理
slice()方法的一个重要应用,是将类似数组的对象转为真正的数组。
Array.prototype.slice.call({ 0: 'a', 1: 'b', length: 2 })
// ['a', 'b']
Array.prototype.slice.call(document.querySelectorAll("div"));
Array.prototype.slice.call(arguments);
上面代码的参数都不是数组,但是通过call方法,在它们上面调用slice()方法,就可以把它们转为真正的数组。
3.数组的拼接
concat :
@params:多个任意类型值
@return:拼接后的新数组(原来数组不变)
let ary1 = [10, 20, 30];
let ary2 = [40, 50, 60];
let res = ary1.concat('二哈', ary2); //里面为空相当于克隆数组
console.log(res); //10,20,30,二哈 40,50,60
4.把数组转化为字符串
toString ; 转化为字符串
@params:把数组转化为字符串
@return:转化后的字符串,(原来的数组不变)
join ; 转化为字符串
@params:指定的分隔符(字符串格式
@return:转化后的字符串,(原来的数组不变)
let ary = [10, 20, 30];
let res = ary.join('|');
console.log(res); // 10|20|30 (string)
res = ary.join('+')
console.log(res); //10+20+30
console.log(eval(res)); //60 eval把字符串转化为js表达式执行
5.检测数组中是否包含某一项
indexof/lastIndexof :检测当前项在数组中第一次或者最后一次出现位置索引值(ie6~8不兼容)
@params:要检索的这一项内容
@return:着一项出现的位置索引值(数字)如果数组中没有这一项,返回结果为-1
还可以验证数组中是否存在某一项元素
缺点:假如数组里面右NaN,我们想要检测这一项是否存在,这里显示无法查询
let ary = [NaN];
console.log(ary.indexOf(NaN)); //-1 无法检测
可以使用findIndex解决
let ary = [1 n, 2, 3, NaN];
let test = ary.findIndex(a => Object.is(NaN, a))
console.log(test); //3
incluedes 也可以验证数组中是否存在某一项元素(存在返回true)
let ary = [10, 20, 30, 10, 20, 30];
console.log(ary.indexOf(20)); //1
console.log(ary.lastIndexOf(20)); //4
if (ary.indexOf('珠峰') === -1) {
console.log('不存在'); //不包在
}
if (ary.includes(10)) { // 如果存在则返回false
console.log('存在'); // 存在
}
6.数组的排序或者排列
reverse
@params:无
@return:排列后的新数组,原来数组发生改变
sort :实现数组的排序
@parame:可以没有,也可以是个函数
@return: 排序后的数组,原来数组也发生改变
let ary = [8, 2, 6, 7, 9, 4];
ary.sort()
console.log(ary); //2,4,6,7,8,9
ary = [12, 15, 9, 28, 10, 22]
console.log(ary.sort()); //10,12,15,22,28,9
如果不传参数,是无法处理10以上数字的排序的(它默认按照每一项第一个字符来排,不是我们需要的结果
let ary = [12, 15, 9, 28, 10, 22];
// ary.sort(function(a,b){....})
ary.sort((a, b) => {
return a - b; //b - a 就是由大到小
})
console.log(ary); // 9 10 12 15 22 28 从小到大
所以要实现多位数正常排序,需要给sort传递一个函数,函数中返回 a-b 实现升序,降序为b-a(冒泡排序为原理)
7.遍历数组
forEach
遍历数组中的每一项
@params:回调函数
@return:原来数组不变
forEach()方法与map()方法很相似,也是对数组的所有成员依次执行参数函数。但是,forEach()方法不返回值,只用来操作数据。这就是说,如果数组遍历的目的是为了得到返回值,那么使用map()方法,否则使用forEach()方法。
let ary = [12, 15, 9, 28, 10, 22];
// 基于原生js循环可以实现
// for (var i = 0; i < ary.length; i++) {
// console.log(ary[i]); //遍历数组
// }
ary.forEach((item, index) => {
console.log(item, index); //item和index为索引值和对应的索引
})
forEach还能传第二个参数,用来改变this指向
let ary = [1,2,3,4,5];
let newAry = [];
ary.forEach(function(value){
this.push(vaule*2) // this=>newAry
},newAry)
//newAry [2,4,6,8,10]
8.Array.prototype
在控制台查看数组所提供得方法,可以基于mdn网站去查阅
9.数组去重
方案一 :
循环原来的数组,把每一项添加到新的数组中,在添加加判断新数组中是否有重复的值
let ary = [1, 2, 3, 1, 2, 3, 1, 1, 2, 2, 3];
let ary1 = [];
for (let i = 0; i < ary.length; i++) {
let item = ary[i];
if (ary1.includes(item)) {
continue;
}
ary1.push(item)
}
console.log(ary1); // 1, 2,3
优化 : 利用forEach循环数组
forEach循环不能中途中断数组(既不能使用continue,break)
let ary = [1, 2, 3, 1, 2, 3, 1, 1, 2, 2, 3, 3];
let ary1 = [];
ary.forEach(item => {
if (ary1.includes(item)) return; //循环中continue结束循环,函数中return结束操作
ary1.push(item);
})
console.log(ary1);
方法三
let ary = [1, 2, 3, 1, 2, 3, 1, 1, 2, 2, 3, 3];
for (var i = 0; i < ary.length; i++) {
let item = ary[i]
// 让当前项和后面的一项进行比较
for (var j = i + 1; j < ary.length; j++) {
var compare = ary[j] //后面拿出来要比较的每一项
// 如果compare与item相等,说明这一项重复,我们需要删除这一项
if (compare === item) {
ary.splice(j, 1);
j--; // 这里我们在删除重复项,数组索引发生改变之后,删除的那一位对应的索引现在是新的未检测的值,我们此时j—--,然后就可以从新检测后面的值
}
}
}
console.log(ary); //数组木有去重,
// 造成的原因为数组塌陷 ,splice方法会改变原来的数组,让索引都发生改变,这个时候我们在默认加一位的话,会让后面的混到前面就,就无法做到去重效果
优化方法
function unique(ary) {
let obj = {};
for(let i = 0; i<ary.length;i++) {
let item = ary[i];
if(typeof obj[item] !== "undefined") {
ary[i] = ary[ary.length-1];
ary.length--;
i--;
continue;
}
obj[item] = item;
}
obj = null;
return ary
}
dds
10.利用数组求最大值,或最小值
// 获取数组中的最大值和最小值
let ary = [12, 23, 121, 24, 121, 42, 54,];
/*
// 解决方案一:先排序,后求值
ary.sort((a, b) => {
return a - b;
})
let min = ary[0];
let max = ary[ary.length - 1];
console.log(min, max); */
// 解决方案二:math.min ,math.max 要求传递数据都是一项项传递进来,获取一堆数中的最大最小,而不是获取一个数组的最大最小
// 1. es6 展开运算符解决
// let min = Math.min(...ary)
// let max = Math.max(...ary)
// // 2. 利用apply来实现即可(this无所谓)主要是利用给apply给函数传参,需要写成一个数组的特征)
// let zuixiao = Math.min.apply(null, ary);
// console.log(min, max);
// console.log(zuixiao);
// 解决方案三: 假设法,(假设第一个值是最大的,让数组中的每一项分别和当前假设的值比较,如果比假设的值大,则把最大的值设为新的值,继续向后比较即可
let max = ary[0];
// for (let i = 1; i < ary.length; i++) {
// let item = ary[i];
// item > max ? max = item : null;
// }
ary.slice(1).forEach(item => {
item > max ? max = item : null;
})
console.log(max);
11.map()
map()方法将数组的所有成员依次传入参数函数,然后把每一次的执行结果组成一个新数组返回。
var numbers = [1, 2, 3];
numbers.map(function (n) {
return n + 1;
});
// [2, 3, 4]
numbers
// [1, 2, 3]
var arr = ['a', 'b', 'c'];
[1, 2].map(function (e) {
return this[e];
}, arr)
// ['b', 'c']
12.filter
forEach()方法与map()方法很相似,也是对数组的所有成员依次执行参数函数。但是,forEach()方法不返回值,只用来操作数据。这就是说,如果数组遍历的目的是为了得到返回值,那么使用map()方法,否则使用forEach()方法。
[1, 2, 3, 4, 5].filter(function (elem) {
return (elem > 3);
})
// [4, 5]
filter()方法的参数函数可以接受三个参数:当前成员,当前位置和整个数组。
[1, 2, 3, 4, 5].filter(function (elem, index, arr) {
return index % 2 === 0;
});
// [1, 3, 5]
filter()方法还可以接受第二个参数,用来绑定参数函数内部的this变量。
var obj = { MAX: 3 };
var myFilter = function (item) {
if (item > this.MAX) return true;
};
var arr = [2, 8, 3, 4, 1, 3, 2, 9];
arr.filter(myFilter, obj) // [8, 4, 9]
上面代码中,过滤器myFilter()内部有this变量,它可以被filter()方法的第二个参数obj绑定,返回大于3的成员。
13.reduce(),reduceRight()
reduce()方法和reduceRight()方法依次处理数组的每个成员,最终累计为一个值。它们的差别是,reduce()是从左到右处理(从第一个成员到最后一个成员),reduceRight()则是从右到左(从最后一个成员到第一个成员),其他完全一样。
[1, 2, 3, 4, 5].reduce(function (a, b) {
console.log(a, b);
return a + b;
})
// 1 2
// 3 3
// 6 4
// 10 5
//最后结果:15
- 第一次执行:a是数组的第一个成员1,b是数组的第二个成员2。
- 第二次执行:a为上一轮的返回值3,b为第三个成员3。
- 第三次执行:a为上一轮的返回值6,b为第四个成员4。
- 第四次执行:a为上一轮返回值10,b为第五个成员5。至此所有成员遍历完成,整个方法的返回值就是最后一轮的返回值15。
reduce()方法和reduceRight()方法的第一个参数都是一个函数。该函数接受以下四个参数。
- 累积变量。第一次执行时,默认为数组的第一个成员;以后每次执行时,都是上一轮的返回值。
- 当前变量。第一次执行时,默认为数组的第二个成员;以后每次执行时,都是下一个成员。
- 当前位置。一个整数,表示第二个参数(当前变量)的位置,默认为1。
- 原数组。
如果要对累积变量指定初值,可以把它放在reduce()方法和reduceRight()方法的第二个参数。
[1, 2, 3, 4, 5].reduce(function (a, b) {
return a + b;
}, 10);
// 25
14.find,findIndex
find() 方法返回通过测试(函数内判断)的数组的第一个元素的值。
find() 方法为数组中的每个元素都调用一次函数执行:
- 当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素,之后的值不会再调用执行函数。
- 如果没有符合条件的元素返回 undefined
注意: find() 对于空数组,函数是不会执行的。
注意: find() 并没有改变数组的原始值。
let ary = [1, 2, 3, 4, 5];
let value = ary.find(function(value) {
return value > 2
})
console.log(value); //3
findIndex则是返回第一个符合条件的索引值
let ary = [1, 2, 3, 4, 5];
let value = ary.findIndex(function(value) {
return value > 2
})
console.log(value); //2