文章目录
- 数组方法(包括es6)
- 1、arr.push()
- 2、arr.pop()
- 3、arr.shift()
- 4、arr.unshift()
- 5、arr.splice(i,n)
- 6、arr.slice(start,end)
- 7、arr.concat()
- 8、arr.join()
- 9、arr.sort()
- 10、arr.reverse()
- 11、arr.forEach(callback)
- 12、arr.map(callback)
- 13、arr.filter(callback)
- 14、arr.every(callback)
- 15、arr.some()
- 16、arr.reduce(callback, initialValue)
- 17、arr.reduceRight(callback, initialValue)
- 18、arr.indexOf()
- 19、arr.lastIndexOf()
- 20、[es6]Array.from()
- 21、Array.of()
- 22、Array.isArray()
- 23、[es6] arr.copyWithin()
- 24、[es6] arr.find(callback)
- 25、[es6] arr.findIndex(callback)
- 26、arr.fill(target, start, end)
- 27、[es6] arr.includes()
- 28、[es6] arr.keys()
- 29、[es6] arr.values()
- 30、[es6] arr.entries()
- ES6对于数组的扩展
- 常用对数组的扩展方法
- 数值千分位格式化的两种简单实现方法
数组方法(包括es6)
1、arr.push()
从后面添加元素,返回值为添加完后的数组的长度 ,改变原数组
a = [1,2,3,4,5]; b = a.push(6,7,8); console.log(b);//8 数组长度 console.log(a);//[1, 2, 3, 4, 5, 6, 7, 8]
2、arr.pop()
从后面删除元素,只能是一个,返回值是删除的元素 (改变原数组)
let arr = [1,2,3,4,5]
console.log(arr.pop()) // 5
console.log(arr) //[1,2,3,4]
3、arr.shift()
从前面删除元素,只能删除一个 返回值是删除的元素(改变原数组)
let arr = [1,2,3,4,5]
console.log(arr.shift()) // 1
console.log(arr) // [2,3,4,5]
4、arr.unshift()
从前面添加元素, 返回值是添加完后的数组的长度(改变原数组)
let arr = [1,2,3,4,5]
console.log(arr.unshift([1,2])) // 6
console.log(arr) //[[1,2],1,2,3,4,5]
5、arr.splice(i,n)
删除从i(索引值)开始之后的那个元素。返回值是删除的元素(改变原数组)
参数: i 索引值 n 个数,n缺省时表示从i往后都删了
let arr = [1,2,3,4,5]
console.log(arr.splice(2,2)) //[3,4]
console.log(arr) // [1,2,5]
6、arr.slice(start,end)
切去索引值start到索引值end的数组,不包含end索引的值,返回值是切出来的数组(不改变原数组)
let arr = [1,2,3,4,5]
console.log(arr.slice(1,3)) // [2,3]
console.log(arr) // [1,2,3,4,5]
7、arr.concat()
连接两个数组 返回值为连接后的新数组(不改变原数组)
var a = [1,2,3],b = [4,5];var c = a.concat(b); a//[1, 2, 3] b//[4,5] c// [1, 2, 3, 4, 5]
8、arr.join()
将数组转为字符串(不改变原数组)
a = [1,2,3];b = a.join(',');
b// "1,2,3"
参数: 字符串
9、arr.sort()
将数组进行排序,返回值是排好的数组,(改变原数组)
说明:如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。
如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:
- 若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
- 若 a 等于 b,则返回 0。
- 若 a 大于 b,则返回一个大于 0 的值。
let arr = [2,10,6,1,4,22,3]
console.log(arr.sort()) // [1, 10, 2, 22, 3, 4, 6]
console.log(arr.sort((a, b) => {return -1})) // [3, 22, 4, 1, 6, 10, 2]
let arr = ['a', 'b', 'c', 'd']
console.log(arr.sort()) // ["a", "b", "c", "d"]
let arr1 = arr.sort((a, b) =>a - b)
console.log(arr, arr1) //[1, 2, 3, 4, 6, 10, 22], [1, 2, 3, 4, 6, 10, 22]
let arr2 = arr.sort((a, b) =>b-a)
console.log(arr2) // [22, 10, 6, 4, 3, 2, 1]
let arr3 = arr.sort((a, b) =>b>a? -1: 1);
console.log(arr3); //[1, 2, 3, 4, 6, 10, 22]
let arr = [{num:2},{num:10},{num:6},{num:1},{num:4},{num:22},{num:3}]
console.log(arr.sort((a, b) => a.num - b.num))// [{num: 1},{num: 2},{num: 3},{num: 4},{num: 6},{num: 10},{num: 22}]
[2,10,6,1,4,22,3].sort(function(a,b){
if(a < b){
return -1;
}else{
return 1
}
})//[1, 2, 3, 4, 6, 10, 22]
[2,10,6,1,4,22,3].sort(function(a,b){
return a-b;
})
10、arr.reverse()
将数组反转,返回值是反转后的数组(改变原数组)
let arr = [1,2,3,4,5]
console.log(arr.reverse()) // [5,4,3,2,1]
console.log(arr) // [5,4,3,2,1]
11、arr.forEach(callback)
常用于遍历数组,注意:如果要终止或者跳出forEach()循环,除非抛出异常,所以想执行一个数组是否满足某种条件然后返回某值,可以用一般的for循环实现,或者用Array.every()或者Array.some();
callback的参数: value --当前索引的值
index --索引
array --原数组
12、arr.map(callback)
映射数组(遍历数组),有return 返回一个新数组 。
callback的参数: value --当前索引的值
index --索引
array --原数组
13、arr.filter(callback)
过滤数组,返回一个满足要求的数组
callback的参数: value --当前索引的值
index --索引
14、arr.every(callback)
依据判断条件,数组的元素是否全满足,若满足则返回ture
callback的参数: value --当前索引的值
index --索引
let arr = [1,2,3,4,5]
let arr1 = arr.every( (value, index) =>value<3)
console.log(arr1) // false
let arr2 = arr.every( (value, index) =>value<6)
console.log(arr2) // true
15、arr.some()
依据判断条件,数组的元素是否有一个满足,若有一个满足则返回ture
callback的参数: value --当前索引的值
index --索引
let arr = [1,2,3,4,5]
let arr1 = arr.some( (value, index) =>value<3)
console.log(arr1) // true
let arr2 = arr.some( (value, index) =>value>6)
console.log(arr2) // false
16、arr.reduce(callback, initialValue)
迭代数组的所有项,累加器,数组中的每个值(从左到右)合并,最终计算为一个值
参数: callback: previousValue 必选 --上一次调用回调返回的值,或者是提供的初始值(initialValue)
currentValue 必选 --数组中当前被处理的数组项
index 可选 --当前数组项在数组中的索引值
array 可选 --原数组
initialValue: 可选 --初始值
实行方法:回调函数第一次执行时,preValue 和 curValue 可以是一个值,如果 initialValue 在调用 reduce() 时被提供,那么第一个 preValue 等于 initialValue ,并且curValue 等于数组中的第一个值;如果initialValue 未被提供,那么preValue 等于数组中的第一个值.
let arr = [0,1,2,3,4]
let arr1 = arr.reduce((preValue, curValue) =>
preValue + curValue
)
console.log(arr1) // 10
reduce的高级用法
计算数组中每个元素出现的次数
let names = ['peter', 'tom', 'mary', 'bob', 'tom','peter'];
let nameNum = names.reduce((pre,cur)=>{
if(cur in pre){
pre[cur]++
}else{
pre[cur] = 1
}
return pre
},{})
console.log(nameNum); //{ peter: 2, tom: 2, mary: 1, bob: 1 }
数组去重
let arr = [1,2,3,4,4,1]
let newArr = arr.reduce((pre,cur)=>{
if(!pre.includes(cur)){
return pre.concat(cur)
}else{
return pre
}
},[])
console.log(newArr);// [1, 2, 3, 4]
将多维数组转化为一维
let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
const newArr = function(arr){
return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?newArr(cur):cur),[])
}
console.log(newArr(arr)); //[0, 1, 2, 3, 4, 5, 6, 7]
17、arr.reduceRight(callback, initialValue)
与arr.reduce()功能一样,不同的是,reduceRight()从数组的末尾向前将数组中的数组项做累加。
实行方法:reduceRight()首次调用回调函数callbackfn时,prevValue 和 curValue 可以是两个值之一。如果调用 reduceRight() 时提供了 initialValue 参数,则 prevValue 等于 initialValue,curValue 等于数组中的最后一个值。如果没有提供 initialValue 参数,则 prevValue 等于数组最后一个值, curValue 等于数组中倒数第二个值。
18、arr.indexOf()
查找某个元素的索引值,若有重复的,则返回第一个查到的索引值若不存在,则返回 -1
19、arr.lastIndexOf()
和arr.indexOf()的功能一样,不同的是从后往前查找
20、[es6]Array.from()
将伪数组变成数组,就是只要有length的就可以转成数组。
let str = '12345'
console.log(Array.from(str)) // ["1", "2", "3", "4", "5"]
let obj = {0:'a',1:'b',length:2}
console.log(Array.from(obj)) // ["a", "b"]
21、Array.of()
将一组值转换成数组,类似于声明数组 —es6
let str = '11'
console.log(Array.of(str)) // ['11']
//等同于
console.log(new Array('11')) // ['11]
22、Array.isArray()
判断是否为数组
23、[es6] arr.copyWithin()
在当前数组内部,将指定位置的数组复制到其他位置,会覆盖原数组项,返回当前数组
参数: target --必选 索引从该位置开始替换数组项
start --可选 索引从该位置开始读取数组项,默认为0.如果为负值,则从右往左读。
end --可选 索引到该位置停止读取的数组项,默认是Array.length,如果是负值,表示倒数
let arr = [1,2,3,4,5,6,7]
let arr1 = arr.copyWithin(1)
console.log(arr1) // [1, 1, 2, 3, 4, 5, 6]
let arr2 = arr.copyWithin(1,2)
console.log(arr2) // [1, 3, 4, 5, 6, 7, 7]
let arr3 = arr.copyWithin(1,2,4)
console.log(arr3) // [1, 3, 4, 4, 5, 6, 7]
let arr = ['a','b', 'c', 'd', 'e','f','g']
let arr1 = arr.copyWithin(2)
console.log(arr1) // ["a", "b", "a", "b", "c", "d", "e"]
let arr2 = arr.copyWithin(1, 2)
console.log(arr2) // ["a", "c", "d", "e", "f", "g", "g"]
let arr3 = arr.copyWithin(1, 2, 4)
console.log(arr3) // ["a", "c", "d", "d", "e", "f", "g"]
let arr4 = arr.copyWithin(1, 2, -2)
console.log(arr4) //["a", "c", "d", "e", "e", "f", "g"]
24、[es6] arr.find(callback)
找到第一个符合条件的数组成员
(未找到返回undefined)
let arr = [1,2,3,4,5,2,4]
let arr1 = arr.find((value, index, array) =>value > 2)
console.log(arr1) // 3
25、[es6] arr.findIndex(callback)
找到第一个符合条件的数组成员的索引值
(未找到返回-1)
26、arr.fill(target, start, end)
使用给定的值,填充一个数组,ps:填充完后会改变原数组
参数: target – 待填充的元素
start – 开始填充的位置-索引
end – 终止填充的位置-索引(不包括该位置)
let arr = [1,2,3,4,5]
let arr1 = arr.fill(5)
console.log(arr1) // [5, 5, 5, 5, 5]
console.log(arr) // [5, 5, 5, 5, 5]
let arr2 = arr.fill(5,2)
console.log(arr2)
let arr3 = arr.fill(5,1,3)
console.log(arr3)
27、[es6] arr.includes()
判断数中是否包含给定的值
ps:与indexOf()的区别:
indexOf() 不能判断NaN,返回为-1 ,includes()则可以判断
let arr = [1,2,3,4,5]
let arr1 = arr.includes(2)
console.log(arr1) // ture
let arr2 = arr.includes(9)
console.log(arr2) // false
let arr3 = [1,2,3,NaN].includes(NaN)
console.log(arr3) // true
28、[es6] arr.keys()
遍历数组的键名
let arr = [1,2,3,4]
let arr2 = arr.keys()//arr2: [object Array Iterator]
for (let key of arr2) {
console.log(key); // 0,1,2,3
}
29、[es6] arr.values()
遍历数组键值
30、[es6] arr.entries()
遍历数组的键名和键值
let arr = [1,2,3,4]
let iterator1 = arr.entries()
for (let e of iterator1) {
console.log(e); // [0,1] [1,2] [2,3] [3,4]
}
var array1 = ['a', 'b', 'c'];
var iterator1 = array1.entries();
console.log(iterator1.next().value); // Array[0, "a"]
console.log(iterator1.next().value); // Array[1, "b"]
entries() 方法返回迭代数组。
迭代数组中每个值 前一个是索引值作为 key, 数组后一个值作为 value。
ES6对于数组的扩展
1、扩展运算符(…),用于将数组转化为逗号分隔的参数序列。
1.1、…实现数组的拷贝
数组是一维数组时,扩展运算符可以深拷贝一个数组(对象同理):
let arr = [1, 2, 3, 4, 5, 6]; let arr1 = [...arr]; arr == arr1 // false当数组为多维时,数组中的数组变成浅拷贝(对象同理):
let arr = [1, 2, 3, 4, 5, 6, [1, 2, 3]]; let arr1 = [...arr]; arr1.push(7); arr1[arr1.length - 2][0] = 100; console.log(arr); //[1, 2, 3, 4, 5, 6,[100, 2, 3]] console.log(arr1); //[1, 2, 3, 4, 5, 6, [100, 2, 3],7]
1.2、合并数组
[...arr,...arr2,...arr3]
// 结合解构赋值,生成剩余数组 -- 扩展运算符只能置于参数最后
let [one,...rest] = [1,2,3,4,5];
one // 1
rest // [2,3,4,5]
// 扩展字符串成数组
[...'babe'] // ["b", "a", "b", "e"]
// 可以把类数组对象转换为真正的数组
function convert2Arr(){
return [...arguments];
}
let result = convert2Arr(1,2,3,4,5);
result // [1,2,3,4,5]
2、[es6] Array.from()
用于将类数组对象、可遍历的对象转为真正的数组
// 类数组对象,key是数组下标,length属性必填病为数字型或可转化位数字的字符串
let obj = {
0: 'hello',
1: 'world',
4: 'outof bounds data',
length: 3
}
Array.from(obj); // ["hello", "world", undefined]
// 根据属性名对应到数组的index, 超过length部分舍弃。没有对应的属性,置为undefined
let obj = {
0: 'hello',
1: 'world',
2: 'outof bounds data',
name: 'tom',
6: 'aloha',
length: '7'
}
Array.from(obj); // ["hello", "world", "outof bounds data", undefined, undefined, undefined, "aloha"]
let obj = {
0: 'hello',
1: 'world',
2: 'outof bounds data'
}
Array.from(obj); // []
// 注意:
// Array.from()是一个很不严谨的角色,只要对象含有length属性,且值为正整数就能转,不保证转出来的东西质量是否符合要求。
Array.from({user:'babe',length:5})
// [undefined, undefined, undefined, undefined, undefined]
// Array.from()可接收第二个参数,用于对数组的每一项进行处理并返回
Array.from([1,2,3],x=>x*x)
// [1, 4, 9]
Array.from([1,2,3],x=>{x*x})
// [undefined, undefined, undefined] --切记处理函数中一定要返回
// Array.from()还可接收第三个参数,这样在处理函数中就可以使用传进去的对象域中的值
let that = {
user:'babe'
}
let obj = {
0:'babe',
1:'zhangsan',
2:'lisi',
length:3
}
let result = Array.from(obj,(user) =>{
if(user == that.user){
return user;
}
return 0;
},that);
result // ["babe", 0, 0]
3、[es6] Array.of()
用于将一组值转换为数组,存在的意义是替代以构造函数的形式创建数组,修复数组创建因参数不一致导致表现形式不同的伪bug
// 以构造函数的形式创建数组
new Array();
new Array(size); // 参数 size 是期望的数组元素个数。返回的数组,length 字段将被设为 size 的值。
new Array(element0, element1, ..., elementn); // 参数 element ..., elementn 是参数列表。当使用这些参数来调用构造函数 Array() 时,新创建的数组的元素就会被初始化为这些值。它的 length 字段也会被设置为参数的个数。
// 原始方式
new Array() // []
new Array(2) // [empty × 2]
new Array(1,2,3,4,5) // [1, 2, 3, 4, 5]
// 先进改良方式
Array.of(); // []
Array.of(2); // [2]
Array.of(1,2,3,4,5); // [1, 2, 3, 4, 5]
常用对数组的扩展方法
3.1、数组去重(一维数组)
var arr = [1, 43, 4, 3, 2, 4, 3];
// 去重后
arr = [1, 43, 4, 3, 2]
传统方法,for循环实现
//方法一: function dedupe(arr) { var rets = []; for (var i = 0; i < arr.length; i ++) { if (!rets.includes(arr[i])) { rets.push(arr[i]); } } return rets; } // 方法二: forEach方法实现 function dedupe(arr) { var rets = []; arr && arr.forEach(function(item){ if (!rets.includes(item)){ rets.push(item); } }); return rets; }ES6方法实现
// es6提供的新的数据结构Set,类似数组,但是成员的值都是唯一的,没有重复的值。 function dedupe(arr) { var newSet = new Set(arr); // arr变成了set的数据结构,并去除了其中重复的元素 return Array.from(newSet); // Array.from方法将set数据结构转为数组数据结构 }
3.2、复杂的数组去重
[1,2,{a:1},3,2,{a:1},[1,2],[1,2]]
//数组中的元素包含对象和数组
function unique(arr) {
const hash = {};
const res = [];
for (let i = 0; i < arr.length; i++) {
if (hash[arr[i]] == null) {
res.push(arr[i]);
hash[arr[i]] = true;
}
}
return res;
}
unique([1,2,{a:1},3,2,{a:1},[1,2],[1,2]]);
// 1, 2, {a: 1}, 3, [1, 2]
3.3、数组去扁平化
数组的扁平化,就是将一个嵌套多层的数组array(嵌套可以是任何层数)转换为只有一层的数组
var arr = [1, 2, 3, [4, 3, [2, 7], 2], 5, [5, 9, 10], 7];
// 去扁平化后
arr = [1, 2, 3, 4, 3, 2, 7, 2, 5, 5, 9, 10, 7];
(1)循环递归实现
// for循环,如果子元素还是数组,则递归调用该方法 function flatten(arr) { var rets = []; for(var i = 0; i < arr.length; i ++) { if (Array.isArray(arr[i])) { rets = rets.concat(flatten(arr[i])); } else { rets.push(arr[i]); } } return rets; } // 使用forEach function flatten(arr) { var rets = []; arr && arr.forEach(function(item) => { if (Array.isArray(item)) { rets = rets.concat(flatten(item)); } else { rets.push(item); } }); return rets; }(2)使用reduce简化代码
function flatten(arr) { return arr.reduce(function(pre, item){ return pre.concat(Array.isArray(item) ? flatten(item) : item); }, []) } //[123,4,5,6].concat({a:'13231'}) => [123,4,5,6,{a:'13231'}]
数值千分位格式化的两种简单实现方法
function formatNumber(num) {
if (isNaN(num)) {
throw new TypeError("num is not a number");
}
var groups = (/([\-\+]?)(\d*)(\.\d+)?/g).exec("" + num),
mask = groups[1], //符号位
integers = (groups[2] || "").split(""), //整数部分
decimal = groups[3] || "", //小数部分
remain = integers.length % 3;
var temp = integers.reduce(function(previousValue, currentValue, index) {
if (index + 1 === remain || (index + 1 - remain) % 3 === 0) {
return previousValue + currentValue + ",";
} else {
return previousValue + currentValue;
}
}, "").replace(/\,$/g, "");
return mask + temp + decimal;
}
Array的reduce方法在IE9以下不支持,不过,我们可以基于ECMAScript 3来实现一个reduce方法。
在JavaScript中,字符串的replace方法的匹配模式参数除了字符串以外还可以是一个正则表达式,下面是利用String.prototype.replace方法来实现千分位格式化的具体代码:
function formatNumber(num) {
if (isNaN(num)) {
throw new TypeError("num is not a number");
}
//小数点前
return ("" + num).replace(/(\d{1,3})(?=(\d{3})+(?:$|\.))/g, "$1,");
}
function formatNumber(num) {
if (isNaN(num)) {
throw new TypeError("num is not a number");
}
//小数点后
return ("" + num).replace(/(\d{1,3})(?!$)/g, "$1,");
}
// exp1(?=exp2):查找 exp2 前面的 exp1。
// exp1(?!exp2):查找后面不是 exp2 的 exp1
//{n} :n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
//{n,m}:m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。
//+ : 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
(\d{1,3})是一个捕获分组,可以用$1来反向引用,?=(\d{3})+(?:$|.)是正向断言,表示匹配1到3个数字后面必须跟3个数字,但不含最后的3个数字或者3个数字和小数点。