1.数组常用方法

方法的作用和含义
方法的实参(类型和含义
方法的返回值
原来数组时候会发生改变

  1. 实现数组增删改的方法(都会修改原来的数组)

push向数组末尾添加内容
@params
多个任意类型
@return
新增数组的长度

  1. let ary = [10, 20];
  2. let res = ary.push(30, 'AA'); //数组方法向后添加
  3. ary[ary.length] = '100' //原生js向数组后添加
  4. console.log(res, ary);

unshift : 向数组开头位置添加内容

  1. let ary = [10, 20];
  2. let res = ary.unshift(30, 'AA'); //数组方法向后添加
  3. console.log(res, ary); //30,AA,10,20

shift删除数组第一项

  1. let ary = [10, 20, 30, 40];
  2. let res = ary.shift(); //数组方法向后添加
  3. console.log(res, ary); //20,30,40
  4. // 基于原生js中的delete 把数组当成普通的对象,确实可以删除某一项内容,但是length不会修改长度,真实项目中杜绝删除的使用

pop : 删除数组最后一项

  1. let ary = [10, 20, 30, 40];
  2. let res = ary.pop(); //数组方法向后添加
  3. console.log(res, ary); //10,20,30
  4. ary.length--;
  5. console.log(ary); //10,20 基于原生js把数组长度减一,默认就是删除最后一项
  6. // 基于原生js中的delete 把数组当成普通的对象,确实可以删除某一项内容,但是length不会修改长度,真实项目中杜绝删除的使用

splice实现数组增加删除修改
@n,m x都是数字,从索引n开始删除m个元素,用x占用原来删除的部分
n,0,x 从索引n开始,一个都不删吗,把x放到x索引n的前面
@return 把删除的部分用新数组存储起来返回

  1. let ary = [10, 20, 30, 40, 50, 60, 70, 80];
  2. // let res = ary.splice(2, 4)
  3. // console.log(res, ary); //4. 10,20,70,80
  4. // res = ary.splice(0);
  5. // console.log(ary, res); //清空一个数组,把原始数组的内容以新数组存储起来,
  6. // 删除最后一项 和第一项
  7. ary.splice(ary.length - 1);
  8. ary.splice(0, 1);
  9. console.log(ary); //20,30,40,50,60,70
  1. let ary = [10, 20, 30, 40, 50, 60]
  2. let res = ary.splice(1, 2, '珠峰');
  3. console.log(res, ary); //10 ,珠峰,40,50,60
  4. ary.splice(3, 0, '呵呵呵');
  5. console.log(ary); //10,珠峰,40,呵呵,50,60
  6. ary.splice(ary.length, 0, 'aaaa');
  7. console.log(ary); //10,珠峰,40,呵呵,50,60,aaa
  8. ary.splice(0, 0, '0000');
  9. console.log(ary);//'000',10,珠峰,40,呵呵,50,60,aaa

2.数组的查询

此组方法,原数组不会发生改变
slice实现数组的查询
@params:n,m,都是从数字开始,从索引n开始,找到索引为m的地方(不包含m项)
@return 把找到的内容一个新的数组的形式返回

  1. let ary = [10, 20, 30, 40, 50];
  2. let res = ary.slice(1, 3);
  3. console.log(res); //20,30
  4. // 如果不写m,则直接从n开始查询到最后一项
  5. let res1 = ary.slice(2);
  6. console.log(res1); //30,40,50
  7. // 数组克隆
  8. res = ary.slice(0);
  9. console.log(res); //10,20,30,40,50

思考:如果n/m为负数会如何,如果n大于m会如何,如果是小数会如何,如果是非有效数字会如何,如果m或者n的值比最大索引大,会如何,2,这张克隆方式为浅克隆,预先深克隆如何处理
slice()方法的一个重要应用,是将类似数组的对象转为真正的数组。

  1. Array.prototype.slice.call({ 0: 'a', 1: 'b', length: 2 })
  2. // ['a', 'b']
  3. Array.prototype.slice.call(document.querySelectorAll("div"));
  4. 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. 累积变量。第一次执行时,默认为数组的第一个成员;以后每次执行时,都是上一轮的返回值。
  2. 当前变量。第一次执行时,默认为数组的第二个成员;以后每次执行时,都是下一个成员。
  3. 当前位置。一个整数,表示第二个参数(当前变量)的位置,默认为1。
  4. 原数组。

如果要对累积变量指定初值,可以把它放在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