数组的常用方法(最全最清晰)
增
1.push()
功能:用于向数组的末尾添加一个或多个元素
返回值:添加元素后新数组的长度
是否改变原数组:是
var arr=[1,2,3,4,5,6];
console.log(arr.push(5)); // 7
2.unshift()
功能:向数组的开头添加一个或多个元素
返回值:添加元素后新数组的长度
是否改变原数组:是
var arr=[1,2,3,4,5,6];
console.log(arr.unshift(7)); // 7
console.log(arr); // [7,1,2,3,4,5,6]
3.concat()
功能:用于连接两个或多个数组
返回值:添加元素后新数组
是否改变原数组:否
var arr=[1,2,3,4,5,6];
var arr1=[9,10,11,12];
console.log( arr.concat(arr1)); // [1, 2, 3, 4, 5, 6, 9, 10, 11, 12]
删
1.shift()
功能:删除数组中第一个元素
返回值:第一个元素的值
是否改变原数组:是
var arr = [1, 2, 3, 4, 5, 6];
console.log(arr.shift()); // 1
console.log(arr) // [2, 3, 4, 5, 6]
2.pop()
功能:删除数组中最后一个元素
返回值:最后一个元素的值
是否改变原数组:是
var arr = [1, 2, 3, 4, 5, 6];
console.log(arr.pop()); // 1
console.log(arr) // [1, 2, 3, 4, 5]
改
1.splice()
功能:用于插入,删除或替换数组的元素
splice(index,num,item1, ..., itemX);
index:必填值,整数,规定添加/删除的位置,使用负数从数组结尾处规定位置;
num:必填值,要删除的数量。如果设置为0,则不会删除项;
item1, ..., itemX:可选,向数组添加新的项。
返回值:当进行删除时返回被删除的项目
是否改变原数组:是
删除功能:
var arr=[1,2,3,4,5,6];
var newArr=arr.splice(0,3) // 从索引0开始 删除3项
console.log(newArr); // [1,2,3]
console.log(arr); // [4,5,6]
删除替换功能:
var arr=[1,2,3,4,5,6];
var newArr=arr.splice(0,2,34) // 从索引0开始 删除2项 用"34"替换
console.log(arr); // [34, 3, 4, 5, 6]
console.log(newArr); // [1,2]
插入功能:
var arr=[1,2,3,4,5,6];
var newArr=arr.splice(1,0,9) // 从索引1开始 删除0项 插入"9"
console.log(newArr) // [] (没有删除,所以无返回值)
console.log(arr); // [1, 9, 2, 3, 4, 5, 6]
2.slice()
功能:从已有数组中返回选定的元素,返回一个新数组,包含从start到end的数组元素
slice(start,end) 前闭后开
start:必传,规定从何处开始选取,如果为负数,规定从数组尾部算起的位置,-1为数组的最后一个元素。
end:可选,如果该参数没有指定,那么切分数组包含从start到数组结束的所有元素,如果这个参数为负数,那么规定是从数组尾部开始算起的元素。
返回值:返回一个子数组,包含从start到end(不包括该元素)的元素
是否改变原数组:否
// 传正值
var arr = [1, 2, 3, 4, 5, 6];
var newArr = arr.slice(0, 4) // 从0开始截取到第4位
console.log(arr); // [1, 2, 3, 4, 5, 6]
console.log(newArr); // [1, 2, 3, 4]
// 传负值
var arr = [1, 2, 3, 4, 5, 6];
var newArr = arr.slice(0, -1) // 从最后一位开始截取1位
console.log(arr); // [1, 2, 3, 4, 5, 6]
console.log(newArr); // [1, 2, 3, 4, 5]
查
1.indexOf()
功能:查找数组中的某一项
返回值:当该项存在于数组中时,返回该项的下标,不存在时,返回-1
是否改变原数组:否
var arr=[1,2,3,4,5,6];
console.log(arr.indexOf(5)); // 4
console.log(arr.indexOf(9)); // -1
2.includes()
功能:查找数组中的某一项
返回值:存在就返回true,不存在就返回false
是否改变原数组:否
var arr = [1, 2, 3, 4, 5, 6];
var a = arr.includes(5);
var b = arr.includes(7);
console.log(arr); // [1, 2, 3, 4, 5, 6]
console.log(a); // true
console.log(b); // false
3.find() es6
功能:查找第一个符合条件的数组元素。它的参数是一个回调函数。
回调函数有三个参数。value:当前的数组元素,index:当前索引值,arr:被查找的数组。
在回调函数中可以写你要查找元素的条件
find()查到到符合条件的就不会往下查找
返回值:当条件成立为true时,返回该元素,如果没有符合条件的元素,返回值为undefined
是否改变原数组:否
var arr = [{ name: "ss", age: 1 }, { name: "dd", age: 3 }, { name: "aa", age: 5 },];
var newArr = arr.find(function (value, index, arr) {
return value.age > 2;
});
console.log(arr); // [{…}, {…}, {…}]
console.log(newArr); // {name: "dd", age: 3}
4.findIndex() es6
功能:查找第一个符合条件的数组元素。它的参数是一个回调函数。
回调函数有三个参数。value:当前的数组元素,index:当前索引值,arr:被查找的数组。
在回调函数中可以写你要查找元素的条件
findIndex()查到到符合条件的就不会往下查找
与find()用法一样
返回值:当条件成立为true时,返回该元素的索引,如果没有符合条件的元素,返回值为-1
是否改变原数组:否
var arr = [{ name: "ss", age: 1 }, { name: "dd", age: 3 }, { name: "aa", age: 5 },];
var newArr = arr.findIndex(function (value, index, arr) {
return value.age > 3;
});
console.log(arr); // [{…}, {…}, {…}]
console.log(newArr); // 2
排序
1.sort()
功能:对数组的元素进行排序,默认排序顺序是根据字符串UniCode码。
返回值:排序后的数组
是否改变原数组:是
// 数字排序
var arr = [99, 5, 20, 4, 54, 23, 18];
var newArr = arr.sort(function (a, b) {
return a - b; // 从小到大排列
});
console.log(newArr); // [4, 5, 18, 20, 23, 54, 99]
console.log(arr); // [4, 5, 18, 20, 23, 54, 99]
// 字母排序(数字同理排序方式为1,2,3)
var arr = ["dog", "pig", "cat"]
console.log(arr.sort()) // ["cat", "dog", "pig"]
console.log(arr) // ["cat", "dog", "pig"]
2.reverse()
功能:对数组的元素进行倒置排列
返回值:排序后的数组
是否改变原数组:是
var arr=[1,2,3,4,5,6];
console.log(arr.reverse()); // [6, 5, 4, 3, 2, 1]
console.log(arr); // [6, 5, 4, 3, 2, 1]
转换方法
1.join()
功能: 将一个数组的所有元素根据传入的参数连接成一个字符串
返回值:修改后的字符串
是否改变原数组:否
var arr = [1, 2, 3, 4, 5, 6];
var newArr = arr.join('')
console.log(newArr); // 123456
var newArr = arr.join('-')
console.log(newArr); // 1-2-3-4-5-6
2.toString()
功能: 把数组替换成字符串
返回值:修改后的字符串(逗号分隔开来)
是否改变原数组:否
var arr=[1,2,3,4,5,6];
var newArr=arr.toString()
console.log(arr); // [1, 2, 3, 4, 5, 6]
console.log(newArr); // 1,2,3,4,5,6
迭代方法
1.forEach() es5
功能: 遍历数组中的每一项,该方法用于调用数组中每一项元素,并将元素传递给回调函数
返回值:无返回值
是否改变原数组:是
用法:array.forEach(function(cunrrent,index,arr){
},thisValue)。
cunrrent:必填,当前元素;
index:可选,当前元素的索引;
arr:可选,当前元素所属的数组对象;
thisValue:可选,传递给函数的值一般一般用this的值,如果这个参数为空,"undefined"会传递给"this"值(这个一般很少用)。
var arr = [{ name: "ss", age: 1 }, { name: "dd", age: 3 }, { name: "aa", age: 5 },];
var newArr = arr.forEach(function (value, index, arr) {
value.age *= 2;
});
console.log(arr); // [{…}, {…}, {…}]
// [{ name: "ss", age: 2 }, { name: "dd", age: 6 }, { name: "aa", age: 10 },];
console.log(newArr); // undefined
2.map() es5
功能: 遍历数组的每一项,数组中的元素为原数组中的每个元素调用函数处理得到的值。
返回值:根据条件返回新数组
是否改变原数组:否
语法:array.map(function(item,index,arr){})
注意:如果return 为条件句则会以数组形式返回true/false
1.map()不会对空数组进行检查。
2.map()不会改变原数组。
3.map()是数组的方法,有一个参数,参数为一个函数,函数中传入三个参数。
参数1:item必填,当前元素的值;
参数2:index可选,当前元素在数组中的索引值;
参数3:arr可选,当前元素所属的数组对象。
var arr = [{ name: "ss", age: 1 }, { name: "dd", age: 3 }, { name: "aa", age: 5 },];
var newArr = arr.map(function (value, index, arr) {
return value.age * 2;
});
var newArrs = arr.map(function (value, index, arr) {
return value.age > 2;
});
console.log(arr); // [{…}, {…}, {…}]
console.log(newArr); // [2, 6, 10]
console.log(newArrs); // [false, true, true]
3.filter() es5
功能: 遍历数组的每一项,数组中的元素为原数组中的每个元素调用函数处理得到的值。
返回值:根据条件返回新数组
是否改变原数组:否
(1)语法:array.filter(function(value,index,arr){},thisValue)
需要一个回调函数用来写过滤的逻辑,把所有符合条件的数组放到新数组中返回,返回一个过滤的新数组,不改变原数组。
(2)参数:
value:必选参数,指向原数组中的当前项;
index:可选项,value的索引;
arr:可选项,当前元素所属的数组对象。
(3)用法:filter它用于Array的某些元素过滤掉,返回剩下的元素。和map()类似,Array的filter()也接收一个函数,和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。其中filter()返回的数组内是所有满足条件的元素,而find()只返回第一个满足条件的元素,如果条件不满足,filter()返回一个空数组,find()返回undefined。
var arr = [{ name: "ss", age: 1 }, { name: "dd", age: 3 }, { name: "aa", age: 5 },];
var newArr = arr.filter(function (value, index, arr) {
return value.age > 2;
});
console.log(arr); // [{…}, {…}, {…}]
console.log(newArr); // [{name: "dd", age: 3},{name: "aa", age: 5}]
如果使用newArr赋值操作的话,则会影响原数组
var arr = [{ name: "ss", age: 1 }, { name: "dd", age: 3 }, { name: "aa", age: 5 },];
var newArr = arr.filter(function (value, index, arr) {
return value.age += 2;
});
console.log(arr);
console.log(newArr);
// [{ name: "ss", age: 3 }, { name: "dd", age: 5 }, { name: "aa", age: 7 },];
4.every() es5
功能: 遍历数组的每一项
返回值:所有元素都满足条件时,则返回true,如果有一个元素不满足条件则返回false
是否改变原数组:否
var arr = [{ name: "ss", age: 1 }, { name: "dd", age: 3 }, { name: "aa", age: 5 },];
var newArr = arr.every(function (value, index, arr) {
return value.age > 3;
});
console.log(arr); // [{…}, {…}, {…}]
console.log(newArr); // false(age有小于3的,所以为false)
5.some() es5
功能: 遍历数组的每一项,与every相反
返回值:当有一个元素满足条件即返回true,都不满足则返回false
是否改变原数组:否
注意:遍历数组时,有一个元素满足条件就返回true,不在向后查找。
var arr = [{ name: "ss", age: 1 }, { name: "dd", age: 3 }, { name: "aa", age: 5 },];
var newArr = arr.some(function (value, index, arr) {
return value.age > 3;
});
console.log(arr); // [{…}, {…}, {…}]
console.log(newArr); // false(age有大于3的,所以为true)
6.reduce() es5
功能: 用于对数组中的每一项求收敛,求和
返回值:以数组形式计算返回结果(最后一次调用函数的返回值)
是否改变原数组:否
语法:array.reduce(function(total, currentValue, currentIndex, arr), initialValue);
/*
1 total: 必需。初始值, 或者计算结束后的返回值。
currentValue: 必需。当前元素。
currentIndex: 可选。当前元素的索引;
arr: 可选。当前元素所属的数组对象。
2 initialValue: 可选。传递给函数的初始值,相当于total的初始值。
*/
1. 求数组项之和
var arr = [1, 2, 3, 4, 5, 6];
var sum = arr.reduce(function (prev, cur) {
return prev + cur;
},0);
console.log(arr); // [1, 2, 3, 4, 5, 6]
console.log(sum); // 21
2. 求数组项最大值
var max = arr.reduce(function (prev, cur) {
return Math.max(prev,cur);
});
console.log(arr); // [1, 2, 3, 4, 5, 6]
console.log(max); // 6
3. 数组去重
var arr = [1, 2, 3, 4, 5, 6, 1, 3];
var newArr = arr.red21uce(function (prev, cur) {
prev.indexOf(cur) === -1 && prev.push(cur);
return prev;
}, []);
console.log(arr) // [1, 2, 3, 4, 5, 6, 1, 3];
console.log(newArr) // [1, 2, 3, 4, 5, 6]
4.二维数组转化为一维
var arr = [1, 2, 3, [6,7], 5, [9,4]];
var sum = arr.reduce(function (prev, cur) {
return prev.concat(cur)
},[]);
console.log(arr); // [1, 2, 3, [6,7], 5, [9,4]]
console.log(sum); // [1, 2, 3, 6, 7, 5, 9, 4]
验证是否为数组
1.instanceof
instanceof运算符用于检验构造函数的prototype属性是否出现在对象的原型链中的任何位置,返回一个布尔值。
let a = [];
a instanceof Array; //true
let b = {};
b instanceof Array; //false
instanceof运算符检测Array.prototype属性是否存在于变量a的原型链上,显然a是一个数组,拥有Array.prototype属性,所以为true。
存在问题
需要注意的是,prototype属性是可以修改的,所以并不是最初判断为true就一定永远为真。
//为body创建并添加一个iframe对象
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
//取得iframe对象的构造数组方法
xArray = window.frames[0].Array;
//通过构造函数获取一个实例
var arr = new xArray(1,2,3);
arr instanceof Array;//false
导致这种问题是因为iframe会产生新的全局环境,它也会拥有自己的Array.prototype属性,让不同环境下的属性相同很明显是不安全的做法,所以Array.prototype !== window.frames[0].Array.prototype,想要arr instanceof Array为true,你得保证arr是由原始Array构造函数创建时才可行。
2.constructor
实例的构造函数属性constructor指向构造函数,那么通过constructor属性也可以判断是否为一个数组。
let a = [1,3,4];
a.constructor === Array;//true
存在问题
同样,这种判断也会存在多个全局环境的问题,导致的问题与instanceof相同。
//为body创建并添加一个iframe标签
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
//取得iframe对象的构造数组方法
xArray = window.frames[window.frames.length-1].Array;
//通过构造函数获取一个实例
var arr = new xArray(1,2,3);
arr.constructor === Array;//false
3.Object.prototype.toString.call()
Object.prototype.toString().call()可以获取到对象的不同类型
let a = [1,2,3]
Object.prototype.toString.call(a) === '[object Array]';//true
它强大的地方在于不仅仅可以检验是否为数组,比如是否是一个函数,是否是数字等等
//检验是否是函数
let a = function () {};
Object.prototype.toString.call(a) === '[object Function]';//true
//检验是否是数字
let b = 1;
Object.prototype.toString.call(a) === '[object Number]';//true
甚至对于多全局环境时, Object.prototype.toString().call()也能符合预期处理判断。
//为body创建并添加一个iframe标签
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
//取得iframe对象的构造数组方法
xArray = window.frames[window.frames.length-1].Array;
//通过构造函数获取一个实例
var arr = new xArray(1,2,3);
console.log(Object.prototype.toString.call(arr) === '[object Array]');//true
4.Array.isArray()
Array.isArray() 用于确定传递的值是否是一个数组,返回一个布尔值。
let a = [1,2,3]
Array.isArray(a);//true
存在问题
Array.isArray() 是在ES5中提出,也就是说在ES5之前可能会存在不支持此方法的情况
而对于ES5之前不支持此方法的问题,我们其实可以做好兼容进行自行封装
var arg = [1, 2];
// console.log(Array.isArray(arg)); IE8以下(不支持ES5) 会报错
if (!Array.isArray) {
Array.isArray = function (arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
};
console.log(Array.isArray(arg)) // true IE8(不支持ES5) 正常
数组去重
1.排序法去重
var arr = [20, 45, 70, 99, 90, 85, 50, 20, 90, 60, true, false, 1, 0];
// (1)对数组进行排序
arr.sort(function (a, b) {
return a - b;
});
// (2)声明一个新数组用于存放去重后的数组
var newArr = [];
// (3)遍历arr,判断arr[i]与arr[i+1]是否一致
for (var i = 0; i < arr.length; i++) {
if (arr[i] !== arr[i + 1]) {
newArr.push(arr[i])
}
};
console.log(arr); // [false, 0, true, 1, 20, 20, 45, 50, 60, 70, 85, 90, 90, 99]
console.log(newArr);// [false, 0, true, 1, 20, 45, 50, 60, 70, 85, 90, 99]
2.开关法去重
var arr = [20, 45, 70, 99, 90, 85, 50, 20, 90, 60];
// (1)声明一个空数组用于存放去重后的数组
var newArr = [];
// (2)遍历arr,检查arr[i]是否存在于newArr中
for (var i = 0; i < arr.length; i++) {
// 设置一个变量buzai,当buzai为true时,将arr[i]存放到newArr中,否则不存放
var buzai = true;
for (var j = 0; j < newArr.length; j++) {
if (arr[i] == newArr[j]) {//在,不能添加将buzai置为false,结束循环
buzai = false;
break;
};
};
if (buzai) {
newArr.push(arr[i]);
};
};
console.log(arr); // [20, 45, 70, 99, 90, 85, 50, 20, 90, 60]
console.log(newArr); // [20, 45, 70, 99, 90, 85, 50, 60]
3.indexOf索引法去重
var arr = [20, 45, 70, 99, 90, 85, 50, 20, 90, 60];
// (1)声明一个空数组用于存放去重后的数组
var newArr = [];
// (2)遍历arr判断arr[i]是否存在于newArr中
for (var i = 0; i < arr.length; i++) {
// (3)检查是否在newArr中
if (newArr.indexOf(arr[i]) == -1) {//不在
newArr.push(arr[i]);
};
};
console.log(arr); // [20, 45, 70, 99, 90, 85, 50, 20, 90, 60]
console.log(newArr); // [20, 45, 70, 99, 90, 85, 50, 60]
4.对象法去重
// 对象法去重的核心思路:对象的属性名不能重复
var arr = [20, 45, 70, 99, 90, 85, 50, 20, 90, 60];
var obj = {};//检测是否有重复元素
var newArr = [];//存储去重后的新数组
for (var i = 0; i < arr.length; i++) {
// 将数组元素作为对象的属性名
if (obj[arr[i]] == undefined) { // 没有重复
newArr.push(arr[i]);
obj[arr[i]] = 1; // 下一次再重复该元素,不在是undefined
};
};
console.log(arr); // [20, 45, 70, 99, 90, 85, 50, 20, 90, 60]
console.log(newArr); // [20, 45, 70, 99, 90, 85, 50, 60]
5.Set方法去重
var arr = [20, 45, 70, 99, 90, 85, 50, 20, 90, 60];
var newArr = [...new Set(arr)];
console.log(arr); // [20, 45, 70, 99, 90, 85, 50, 20, 90, 60]
console.log(newArr); // [20, 45, 70, 99, 90, 85, 50, 60]
var arr = [20, 45, 70, 99, 90, 85, 50, 20, 90, 60];
var newArr = arr.reduce(function (prev, cur) {
prev.indexOf(cur) === -1 && prev.push(cur);
return prev;
}, []);
console.log(arr) // [20, 45, 70, 99, 90, 85, 50, 20, 90, 60];
console.log(newArr) // [20, 45, 70, 99, 90, 85, 50, 60]
求数组最大值
1.Math.max + 扩展运算符 es6
let arr = [1, 20 , -3 , 15 , 6 , -87 , 12 , 123]
let arrayMax = Math.max(...arr);
console.log(arrayMax) // 123
2.Math.max + apply() es5
let arr = [1, 20 , -3 , 15 , 6 , -87 , 12 , 123]
let arrayMax = Math.max.apply(null,arr)
console.log(arrayMax) // 123
3.for循环
let arr = [1, 20 , -3 , 15 , 6 , -87 , 12 , 123];
let arrayMax = arr[0];
for (let i = 0; i < arr.length - 1; i++) {
// 方法1
max = max < arr[i+1] ? arr[i+1] : max
// 方法2
// if( max < arr[i] ){
// max = arr[i];
// }
}
console.log(arrayMax) // 123
4.递归
let arr = [1, 20 , -3 , 15 , 6 , -87 , 12 , 123];
var max = arr[0];
function findMax( i ){
if( i == arr.length ) return max;
if( max < arr[i] ) max = arr[i];
findMax(i+1);
}
findMax(1);
console.log(max); // 123
5.reduce es5
let arr = [1, 20 , -3 , 15 , 6 , -87 , 12 , 123];
let arrayMax = arr.reduce((num1, num2) => {
return num1 > num2 ? num1 : num2}
)
console.log(arrayMax) // 123
6.sort
let arr = [1, 20 , -3 , 15 , 6 , -87 , 12 , 123];
let arrayMax = arr.sort((a, b) => {
return a - b
})
console.log(arrayMax[arrayMax.length - 1]) // 123(最大值)
console.log(arrayMax[0]) // -87(最小值)
7.多维数组取最大值
let arr = [1,20,-3,[15,6,-87],12,[9,7,123]]
var newArr=arr.join(",").split(","); // 转化为一维数组
console.log(newArr) // ["1", "20", "-3", "15", "6", "-87", "12", "9", "7", "123"]
console.log(Math.max.apply(null,newArr)); // 123(最大值)
console.log(Math.min.apply(null,newArr)); // -87(最小值)
其他封装方法
1.多维数组判断是否为0
ArrremoveEmptyAndRepeat(arr) {
let endArr = [];
let status = true;
arr.forEach((obj) => {
endArr = [...new Set(obj)];
endArr = endArr.filter((s) => {
return !!s;
});
if (endArr.length) {
status = false;
}
});
return status;
},