在实际开发中易忘记或混淆,要度娘一下,所以来一个系统点的复习
数组的一些方法
push() 和 pop()
unshift() 和 shift()
reverse()
sort()
splice()
slice()
split()
join()
concat()
indexOf() 和 lastIndexOf()
toLocateString()
toStrigin()
includes() (ES7)
copyWithin() (ES6新增)
fill() (ES6新增)
forEach() (ES5新增)
map() (ES5新增)
filter() (ES5新增)
every() (ES5新增)
some() (ES5新增)
reduce() (ES5新增)
reduceRight() (ES5新增)
`改变`原数组的方法: (9个)
ES5:
arr.pop() / arr.shift() / arr.push() / arr.unshift() / arr.reverse() / arr.splice() / arr.sort()
ES6:
arr.copyWithin() / arr.fill()
`不改变`原数组的方法: (8个)
ES5:
arr.join() / arr.toLocateString() / arr.toStrigin() / arr.slice() /
arr.cancat() / arr.indexOf() / arr.lastIndexOf()
ES7:
arr.includes()
`遍历方法:`
js中遍历数组并不会改变原始数组: (12个)
ES5:
forEach() / map() / filter() / every() / some() / reduce() / reduceRight()
ES6:
find() / findIndex() / keys() / values() / entries()
名称 | 描述 | 数组改变 | 备注 |
---|---|---|---|
push() 和 pop() | 添加或删除 最后一项 | 原改变 返回 长度 或 值 | |
unshift() 和 shift() | 添加或删除 第一项 | 原改变 返回 长度 或 值 | |
reverse() | 反转数组顺序 | 原数组被改变 | |
sort() | 从小到大排序 | 原数组被改变 | arr.sort((a,b) => a-b) |
splice() | 删除、插入和替换 | 原数组被改变 返回删除的项 | [位置,个数,替换值] |
slice() | 返回从原数组中指定开始下标到结束下标之间的项组成的新数组 | 原数组不变 | 参数1包含,参数2不包含 |
split() | 把一个字符串分割成字符串数组 | 原数组不变 | 非数组方法 易混淆 |
join() | 数组转换成字符串,默认逗号 | 原数组不变 | join(“-”) |
concat() | 将参数添加到原数组中 | 原数组不变 | arr.concat(8,[9,7]) |
indexOf() 和 lastIndexOf() | 从前 或 从后 参数:(要查的项,起点索引) | 原数组不变 | 不存在返回-1 |
toLocateString() | 把数组转换成本地约定的字符串 | ||
toStrigin() | 把每个元素转换为字符串,然后以逗号连接输出显示 | ||
includes() | 查找数组是否包含某个元素 | 返回布尔 | |
copyWithin() | 指定位置的成员复制到其他位置 | ||
fill() | 使用给定值,填充一个数组 | 三个参数 | |
数组循环 | |||
forEach() | 对数组进行遍历循环 | 没有返回值 | |
map() | 值“映射”,对数组中的每一项运行给定函数 | 返回每次函数调用的结果组成的数组 | |
filter() | “过滤”功能,对数组中的每一项运行给定函数 | 返回满足过滤条件组成的数组 | |
every() | 判断数组中每一项都是否满足条件 | 所有项都满足,才会返回true | |
some() | 判断数组中每一项都是否满足条件 | 只要有一项满足 ,才会返回true | |
reduce() | 对数组中的每个元素执行函数 | 求值 | |
reduceRight() | |||
isArray() | 判断是否是一个js数组 | ||
Array.of() | 返回由所有参数值组成的数组,如果没有参数,就返回一个空数组 | 创建数组 | ES6 |
Arrar.from() | 将两类对象转为真正的数组 | 三个参数 | ES6 |
方法
push() 和 pop() 原数组改变
push(): 把里面的内容添加到数组末尾,并返回修改后的长度。
pop():移除数组最后一项,返回移除的那个值,减少数组的length。
var arr = ["Lily","lucy","Tom"];
var count = arr.push("Jack","Sean");
console.log(count); // 5
console.log(arr); // ["Lily", "lucy", "Tom", "Jack", "Sean"]
var item = arr.pop();
console.log(item); // Sean
console.log(arr); // ["Lily", "lucy", "Tom", "Jack"]
unshift() 和 shift() 原数组改变
shift():删除原数组第一项,并返回删除元素的值;如果数组为空则返回undefined 。
unshift:将参数添加到原数组开头,并返回数组的长度 。
var arr = ["Lily","lucy","Tom"];
var count = arr.unshift("Jack","Sean");
console.log(count); // 5
console.log(arr); //["Jack", "Sean", "Lily", "lucy", "Tom"]
var item = arr.shift();
console.log(item); // Jack
console.log(arr); // ["Sean", "Lily", "lucy", "Tom"]
reverse() 原数组改变
reverse():反转数组项的顺序。
var arr = [13, 24, 51, 3];
console.log(arr.reverse()); //[3, 51, 24, 13]
console.log(arr); //[3, 51, 24, 13](原数组改变)
sort() 原数组改变
sort():将数组里的项从小到大排序
var arr1 = ["a", "d", "c", "b"];
console.log(arr1.sort()); // ["a", "b", "c", "d"]
`排序的应用`
var array = [10, 1, 3, 4,20,4,25,8];
array.sort(function(a,b){
return a-b;
});
console.log(array); // [1,3,4,4,8,10,20,25]; // 倒序改为 b-a
// 可以简写为 array.sort((a,b) => a-b)
`数组多条件排序`
var array = [{id:10,age:2},{id:5,age:4},{id:6,age:10},{id:9,age:6},{id:2,age:8},{id:10,age:9}];
array.sort(function(a,b){
if(a.id === b.id){// 如果id的值相等,按照age的值降序
return b.age - a.age
}else{ // 如果id的值不相等,按照id的值升序
return a.id - b.id
}
})
// [{"id":2,"age":8},{"id":5,"age":4},{"id":6,"age":10},{"id":9,"age":6},{"id":10,"age":9},{"id":10,"age":2}]
// 若为简单的数字的数组对象排序 array.sort((a,b) => a.id-b.id)
splice() 原数组改变
splice():删除、插入和替换。
删除:指定 2 个参数:要删除的第一项的位置和要删除的项数。
书写格式:arr.splice( 1 , 3 )
插入:可以向指定位置插入任意数量的项,只需提供 3 个参数:起始位置、 0(要删除的项数)和要插入的项。
书写格式:arr.splice( 2,0,4,6 )
替换:可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定 3 个参数:起始位置、要删除的项数和要插入的任意数量的项。插入的项数不必与删除的项数相等。
var arr = [1,3,5,7,9,11];
var arrRemoved = arr.splice(0,2);
console.log(arr); //[5, 7, 9, 11]
console.log(arrRemoved); //[1, 3]
var arrRemoved2 = arr.splice(2,0,4,6);
console.log(arr); // [5, 7, 4, 6, 9, 11]
console.log(arrRemoved2); // []
var arrRemoved3 = arr.splice(1,1,2,4);
console.log(arr); // [5, 2, 4, 4, 6, 9, 11]
console.log(arrRemoved3); //[7]
slice() 原数组不变
slice(): 切割数组, 浅拷贝到一个新数组对象,且原数组不会被修改
返回从原数组中指定开始下标到结束下标之间的项组成的新数组。
slice()方法可以接受一或两个参数,即要返回项的起始和结束位置。
在只有一个参数的情况下, slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。
如果有两个参数,该方法返回起始和结束位置之间的项——但不包括结束位置的项。
注意:字符串也有一个slice() 方法是用来提取字符串的,不要弄混了。
'This is my car'.slice(5) //is my car
'This is my car'.slice(5, 10) //is my
var arr = [1,3,5,7,9,11];
var arrCopy = arr.slice(1);
var arrCopy2 = arr.slice(1,4);
var arrCopy3 = arr.slice(1,-2);
var arrCopy4 = arr.slice(-4,-1);
console.log(arr); //[1, 3, 5, 7, 9, 11](原数组没变)
console.log(arrCopy); //[3, 5, 7, 9, 11]
console.log(arrCopy2); //[3, 5, 7]
console.log(arrCopy3); //[3, 5, 7]
console.log(arrCopy4); //[5, 7, 9]
split() 字符串操作 (易混淆)
split() : 切割字符串,结果返回由字符串元素组成的一个列表
string.split(s[, sep[, maxsplit]]),针对string类型的split()函数。
1. 无参数的情况
a="my name is zhangkang"
a=a.split() // ['my', 'name', 'is', 'zhangkang']
2. 有参数的情况
d="my,name,is,zhangkang"
e="my;name;is;zhangkang"
d=d.split(",") // ['my', 'name', 'is', 'zhangkang']
e=e.split(";") // ['my', 'name', 'is', 'zhangkang']
3. 当具有两个参数的情况
a="My,name,is,zhangkang,and,I,am,a,student"
b1=a.split(",",1) // ['My', 'name,is,zhangkang,and,I,am,a,student']
b2=a.split(",",2) // ['My', 'name', 'is,zhangkang,and,I,am,a,student']
b8=a.split(",",8) // ['My', 'name', 'is', 'zhangkang', 'and', 'I', 'am', 'a', 'student']
b9=a.split(",",9) // ['My', 'name', 'is', 'zhangkang', 'and', 'I', 'am', 'a', 'student']
join()
join,就是把数组转换成字符串,然后给他规定个连接字符,默认的是逗号( ,)
var arr = [1,2,3];
console.log(arr.join()); // 1,2,3
console.log(arr.join("-")); // 1-2-3
console.log(arr); // [1, 2, 3](原数组不变)
concat()
concat() :将参数添加到原数组中。这个方法会先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。在没有给 concat()方法传递参数的情况下,它只是复制当前数组并返回副本。
var arr = [1,3,5,7];
var arrCopy = arr.concat(9,[11,13]);
console.log(arrCopy); //[1, 3, 5, 7, 9, 11, 13]
console.log(arr); // [1, 3, 5, 7](原数组未被修改)
ES6扩展运算符...合并数组
let a = [2, 3, 4, 5]
let b = [ 4,...a, 4, 4]
console.log(a,b); // [2, 3, 4, 5] [4,2,3,4,5,4,4]
indexOf() 和 lastIndexOf()
indexOf():接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的开头(位置 0)开始向后查找。
书写格式:arr.indexof( 5 )
lastIndexOf:接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的末尾开始向前查找。
书写格式:arr.lastIndexOf( 5,4 )
var arr = [1,3,5,7,7,5,3,1];
console.log(arr.indexOf(5)); //2
console.log(arr.lastIndexOf(5)); //5
console.log(arr.indexOf(5,2)); //2
console.log(arr.lastIndexOf(5,4)); //2
console.log(arr.indexOf("5")); //-1 没有返回-1
toLocateString()
toLocalString():把数组转换成本地约定的字符串
var a = [1,2,3,4,5]; //定义数组
var s = a.toLocaleString(); //把数组转换为本地字符串
console.log(s); //返回字符串“1,2,3,4,5”
toStrigin()
toString():把每个元素转换为字符串,然后以逗号连接输出显示。
var a = [1,2,3,4,5,6,7,8,9,0]; //定义数组
var s = a.toString(); //把数组转换为字符串
console.log(s); //返回字符串“1,2,3,4,5,6,7,8,9,0”
console.log(typeof s); //返回字符串string,说明是字符串类型
var a = [1,[2,3],[4,5]],[6,[7,[8,9],0]]]; //定义多维数组
var s = a.toString(); //把数组转换为字符串
console.log(S); //返回字符串“1,2,3,4,5,6,7,8,9,0”
includes() (ES7)
includes() : 查找数组是否包含某个元素 返回布尔
参数:
searchElement(必须):被查找的元素
fromIndex(可选):默认值为0,参数表示搜索的起始位置,接受负值。正值超过数组长度,数组不会被搜索,返回false。负值绝对值超过长数组度,重置从0开始搜索。
includes方法是为了弥补indexOf方法的缺陷而出现的:
indexOf方法不能识别NaN
indexOf方法检查是否包含某个值不够语义化,需要判断是否不等于-1,表达不够直观
let a=['OB','Koro1',1,NaN];
let b=a.includes(NaN); // true 识别NaN
let b=a.includes('Koro1',100); // false 超过数组长度 不搜索
let b=a.includes('Koro1',-3); // true 从倒数第三个元素开始搜索
let b=a.includes('Koro1',-100); // true 负值绝对值超过数组长度,搜索整个数组
copyWithin() (ES6新增) 改变原数组
copyWithin() :指定位置的成员复制到其他位置
语法:arr.copyWithin(index, start, end)
第一个参数:复制到指定目标索引位置。
第二个参数:元素复制的起始位置 (可选)
第三个参数:停止复制的索引位置 (默认为 array.length)。如果为负值,表示倒数。(可选)
let arr = [1, 2, 3, 4, 5, 6];
let a = arr.copyWithin(2, 0, 3);
console.log(arr)// [1, 2, 1, 2, 3, 6]
fill() (ES6新增) 改变原数组
fill():数组的填充 使用给定值,填充一个数组
语法:arr.fill(value, start, end)
value 必需。填充的值。
start 可选。开始填充位置。
end 可选。停止填充位置 (默认为 array.length)
let arr = new Array(3)
arr.fill('填充')
console.log(arr)//["填充", "填充", "填充"]
arr.fill('位置', 0, 1)
console.log(arr)// ["位置", "填充", "填充"]
遍历方法
forEach()
forEach():对数组进行遍历循环,对数组中的每一项运行给定函数。
这个方法没有返回值。
参数都是function类型,默认有传参,参数分别为:(遍历的数组内容,对应的数组索引,数组本身)
- currentValue(必须),数组当前元素的值
- index(可选), 当前元素的索引值
- arr(可选),数组对象本身
无法中途退出循环,只能用return退出本次回调,进行下一次回调。
它总是返回 undefined值,即使你return了一个
var arr = [1, 2, 3, 4, 5];
arr.forEach(function(x, index, a){
console.log(x + '|' + index + '|' + (a === arr));
});
// 输出为:
// 1|0|true
// 2|1|true
// 3|2|true
// 4|3|true
// 5|4|true
let a = [1, 2, ,3]; // 最后第二个元素是空的,不会遍历(undefined、null会遍历)
let obj = { name: 'OBKoro1' };
let result = a.forEach(function (value, index, array) {
a[3] = '改变元素';
a.push('添加到尾端,不会被遍历')
console.log(value, 'forEach传递的第一个参数'); // 分别打印 1 ,2 ,改变元素
console.log(this.name); // OBKoro1 打印三次 this绑定在obj对象上
// break; // break会报错
return value; // return只能结束本次回调 会执行下次回调
console.log('不会执行,因为return 会执行下一次循环回调')
}, obj);
console.log(result); // 即使return了一个值,也还是返回undefined
// 回调函数也接受接头函数写法
map()
map():指“映射”,对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
- currentValue(必须),数组当前元素的值
- index(可选), 当前元素的索引值
- arr(可选),数组对象本身
var arr = [1, 2, 3, 4, 5];
var arr2 = arr.map(function(item){
return item*item;
});
console.log(arr2); //[1, 4, 9, 16, 25]
filter()
filter():“过滤”功能,数组中的每一项运行给定函数,返回满足过滤条件组成的数组。
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var arr2 = arr.filter(function(x, index) {
return index % 3 === 0 || x >= 8;
});
console.log(arr2); //[1, 4, 7, 8, 9, 10]
every()
every():判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回true。
var arr = [1, 2, 3, 4, 5];
var arr2 = arr.every(function(x) {
return x < 10;
});
console.log(arr2); //true
var arr3 = arr.every(function(x) {
return x < 3;
});
console.log(arr3); // false
some()
some():判断数组中是否存在满足条件的项,只要有一项满足条件,就会返回true。
var arr = [1, 2, 3, 4, 5];
var arr2 = arr.some(function(x) {
return x < 3;
});
console.log(arr2); //true
var arr3 = arr.some(function(x) {
return x < 1;
});
console.log(arr3); // false
reduce() (ES5新增)
reduce() :方法对累加器和数组中的每个元素(从左到右)应用一个函数,最终合并为一个值。
// 回调函数的参数
- total(必须),初始值, 或者上一次调用回调返回的值
- currentValue(必须),数组当前元素的值
- index(可选), 当前元素的索引值
- arr(可选),数组对象本身
// 数组求和
let sum = [0, 1, 2, 3].reduce(function (a, b) {
return a + b;
}, 0);
// 6
// 将二维数组转化为一维 将数组元素展开
let flattened = [[0, 1], [2, 3], [4, 5]].reduce(
(a, b) => a.concat(b),
[]
);
// [0, 1, 2, 3, 4, 5]
reduceRight() (ES5新增)
从右至左累加
除了与reduce执行方向相反外,其他完全与其一致
find() 和 findIndex() (ES6)
find()定义:用于找出第一个符合条件的数组成员,并返回该成员,如果没有符合条件的成员,则返回undefined。
findIndex()定义:返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。
let new_array = arr.find(function(currentValue, index, arr), thisArg)
let new_array = arr.findIndex(function(currentValue, index, arr), thisArg)
// 回调函数的参数
1. currentValue(必须),数组当前元素的值
2. index(可选), 当前元素的索引值
3. arr(可选),数组对象本身
这两个方法都可以识别NaN,弥补了indexOf的不足.
// find
let a = [1, 4, -5, 10].find((n) => n < 0); // 返回元素-5
let b = [1, 4, -5, 10,NaN].find((n) => Object.is(NaN, n)); // 返回元素NaN
// findIndex
let a = [1, 4, -5, 10].findIndex((n) => n < 0); // 返回索引2
let b = [1, 4, -5, 10,NaN].findIndex((n) => Object.is(NaN, n)); // 返回索引4
keys() 遍历键名 / values() 遍历键值/ entries() 遍历键值对 (ES6)
分别是 遍历键名、遍历键值、遍历键名+键值
三个方法都返回一个新的 Array Iterator 对象,对象根据方法不同包含不同的值。
for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1
for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a'
// 'b'
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
// 0 "a"
// 1 "b"
在for..of中如果遍历中途要退出,可以使用break退出循环。
如果不使用for...of循环,可以手动调用遍历器对象的next方法,进行遍历:
let letter = ['a', 'b', 'c'];
let entries = letter.entries();
console.log(entries.next().value); // [0, 'a']
console.log(entries.next().value); // [1, 'b']
console.log(entries.next().value); // [2, 'c']
flat()
深度遍历展开数组
参数: depth(可选): 提取嵌套数组的结构深度,默认为1。
返回值:展开后的新数组。
flat方法会移除数组中的空白项
若不清楚有多少层嵌套,可以直接用 Infinity 设置,就可全部展开
Infinity 正无穷大的数值。
let arr = [1,2,[3,[4,[5]]],6]
let one = arr.flat()
console.log(one)//[1, 2, 3, Array(2), 6]
let inf = arr.flat(Infinity)
console.log(inf)//[1, 2, 3, 4, 5, 6]
一些常用的例子
多层数组去重 再排序
let arr = [1,3,2,4,8,6,[5,1,3,5,9,10,5,[1,5,3,6,7,8,11,7,66]]]
let newarr = Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>a-b)
console.log(newarr)//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 66]
数组打乱
实现原理是 循环数组 在每次遍历中产生一个0 ~ length - 1的数,该数代表本次循环要随机交换的位置。将本次循环当前位置的数和随机位置的数进行交换。
var arr = [1,2,3,4,5,6,7,8,9]
for(let i =0;i<arr.length;i++){
let sum = parseInt(Math.random()*(arr.length-1))
let copyarr = arr[i];
arr[i] = arr[sum]
arr[sum] = copyarr
}
console.log(arr)
数组去重 - ES6中的 Set 方法去重
let arr = [1,0,0,2,9,8,3,1];
function unique(arr) {
return Array.from(new Set(arr))
}
console.log(unique(arr)); // [1,0,2,9,8,3]
或
console.log(...new Set(arr)); // [1,0,2,9,8,3]
数组去重 - 利用数组的includes去重
var arr = [-1, 0, 8, -3, -1, 5, 5, 7];
function unique(arr) {
var arr1 = [];
for (var i = 0, len = arr.length; i < len; i++) {
if (!arr1.includes(arr[i])) { // 检索arr1中是否含有arr中的值
arr1.push(arr[i]);
}
}
return arr1;
}
console.log(unique(arr)); // -1, 0, 8, -3, 5, 7
数组去重 - 利用数组的filter方法去重
var arr = [1, 2, 8, 9, 5, 8, 4, 0, 4];
/*
模拟: 原始数组:[1,2,8,9,5,8,4,0,4]
索引值:0,1,2,3,4,5,6,7,8
伪新数组:[1,2,8,9,5,8,4,0,4]
使用indexOf方法找到数组中的元素在元素在中第一次出现的索引值
索引值:0,1,2,3,4,2,6,7,6
返回前后索引值相同的元素:
新数组:[1,2,8,9,5,4,0]
*/
function unique(arr) {
// 如果新数组的当前元素的索引值 == 该元素在原始数组中的第一个索引,则返回当前元素
return arr.filter(function (item, index) {
return arr.indexOf(item, 0) === index;
});
}
console.log(unique(arr)); // 1, 2, 8, 9, 5, 4, 0
数组去重 - 利用函数递归去重
var arr = [1, 1, 5, 6, 0, 9, 3, 0, 6]
function unique(arr) {
var arr1 = arr;
var len = arr1.length;
arr1.sort((a, b) => {
return a - b
})
function loop(index) {
if (index >= 1) {
if (arr1[index] === arr1[index - 1]) {
arr1.splice(index, 1);
}
loop(index - 1); // 递归loop,然后数组去重
}
}
loop(len - 1);
return arr1
}
console.log(unique(arr)); // 0, 1, 3, 5, 6, 9
数组排序
简单排序
// 简单排序
function sortNumber(a,b){
return a - b
}
var arr = ['10','5','36','3','12','8','24'];
console.log(arr.sort(sortNumber)); //["3", "5", "8", "10", "12", "24", "36"]
console.log(arr); //数组本身发生变化 //["3", "5", "8", "10", "12", "24", "36"]
快速排序 - 冒泡排序 - 插入排序
// 快速排序
var quickSort = function( arr) {
if(arr.length < 1) { //如果数组就是一项,那么可以直接返回
return arr;
}
var centerIndex = Math. floor(arr.length / 2); //获取数组中间的索引
var centerValue = arr[centerIndex]; //获取数组中间项
var left = [], right = [];
for( var i = 0; i < arr.lenght; i ++){
if(arr[i] < centerValue){
left. push(arr[i]);
} else{
right. push(arr[i]);
}
}
return quickSort(left). contanct([centerValue], quickSort(right)); //递归调用
}
// 冒泡排序
var bubbleSort = function( arr) {
var len = arr.length;
for( var i = 0; i < len; i ++){
for( var j = 0; i < len - 1 - i; i ++){
if(arr[j] > arr[j + 1]) { //相邻元素两两对比
var temp = arr[j + 1]; //元素交换
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
// 插入排序
var insertSort = function( arr) {
var len = arr.length;
var preIndex, current;
for( var i = 1; i < len; i ++){
preIndex = i - 1;
current = arr[i];
while(preIndex >= 0 && arr[preIndex] > current){
arr[preIndex + 1] = arr[preIndex];
preIndex --;
}
arr[preIndex + 1] = current;
}
return arr;
}