【Js】数组(包括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个数字和小数点。


版权声明:本文为m0_57135756原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。