zoukankan      html  css  js  c++  java
  • Javascript中数组方法和方法的扩展

    1.数组实例方法的练习

      1.1:reduce()

      1.2:map()

      1.3:sort()

      1.4:slice()

      1.5:push()

      1.6:实例方法习题

    2.数组方法的扩展

    1.数组实例方法的练习

      首先,我们应该知道数组实例方法有哪些。

        console.log(Object.getOwnPropertyNames(Array));
        // ["isArray", "concat", "lastIndexOf", "indexOf", "forEach", "map", "filter", "every", "some", "reduce", "reduceRight", "join", "reverse", "sort", "push", "pop", "shift", "unshift", "splice", "slice", "from", "of", "prototype", "length", "name"]

      上面代码中,使用对象的原生方法getOwnPropertyNames方法来返回对象实例的所有方法。

      下面对一些实例方法做一些简单的介绍。

      1.1:reduce方法

      reduce方法和reduceRight方法都是依次处理数组的每个成员,最终累计为一个值。它们的差别是,reduce是从左到右处理(从第一个成员到最后一个成员),reduceRight则是从右到左(从最后一个成员到第一个成员),其他完全一样。

      这两个方法的第一个参数都是一个函数。该函数接受以下四个参数。

        累积变量,默认为数组的第一个成员

        当前变量,默认为数组的第二个成员

        当前位置(从0开始)

        原数组

      只有前两个才是必须传入的,reduce方法最常用的就是用于数组元素的相加,然后返回累加的值

    1     var arr = [1,2,3,4,5];
    2 
    3     function sum(first,last){
    4         return first+last;
    5     }
    6 
    7     console.log(arr.reduce(sum))    //15

       针对reduce()方法,我重新写了一篇详细的文章,传送门:reduce()方法解析

      1.2:map()

      map方法对数组的所有成员依次调用一个函数,根据函数结果返回一个新数组。要注意的是,map方法返回一个新数组,而原数组是没有发生变化的。

    1     var arr = [1,2,3,4,5];
    2 
    3     var newArr = arr.map(function(value, index) {
    4         return value+1;
    5     });
    6 
    7     console.log(newArr);    // [2, 3, 4, 5, 6]
    8     console.log(arr);    //  [1, 2, 3, 4, 5]

      上面代码中,arr数组的所有成员都加上1,组成一个新数组返回,原数组没有变化。

      map方法接受一个函数作为参数。该函数调用时,map方法会将其传入三个参数,分别是当前成员、当前位置和数组本身。

      1.3:sort()

      sort方法对数组成员进行排序,默认是按照ascii字母顺序排序。排序后,原数组将被改变

    1     var arr1 = [5,6,7,2,6,8,1];
    2     console.log(arr1.sort()); //[1, 2, 5, 6, 6, 7, 8]
    3    console.log(arr1);    //[1, 2, 5, 6, 6, 7, 8]
    4     var arr2 = [1,2,3,11,22,33];
    5     console.log(arr2.sort());    //[1, 11, 2, 22, 3, 33]
    6 console.log(arr2);      //[1, 11, 2, 22, 3, 33]

      如果要让sort方法正常排序,可以传入一个函数。函数带有两个参数,表示进行比较的两个元素。

        var arr2 = [1,2,3,11,22,33];
        console.log(arr2.sort(function(a,b){
            return a - b;
        }));    // [1, 2, 3, 11, 22, 33]

      

      1.4:slice()

      slice方法用于提取原数组的一部分,返回一个新数组,原数组不变。它的第一个参数为起始位置(从0开始),第二个参数为终止位置(但该位置的元素本身不包括在内)。如果省略第二个参数,则一直返回到原数组的最后一个成员。

    1     var arr = [1,2,3,4,5];
    2 
    3     console.log(arr.slice(0));    // [1, 2, 3, 4, 5]
    4     console.log(arr.slice(1,2));    //[2]
    5     console.log(arr.slice(2,5));    //[3, 4, 5]
    6     console.log(arr.slice(3));    //[4, 5]
    7     console.log(arr);    //[1, 2, 3, 4, 5]

      如果slice为负数,则表示倒数计算的位置。

    1     var arr = [1,2,3,4,5];
    2 
    3     console.log(arr.slice(-3));//[3, 4, 5]
    4     console.log(arr.slice(-3,-1));// [3, 4]
    5     console.log(arr);    // [1, 2, 3, 4, 5]

      注意,传入负数时,index值是从-1开始计算的。而传入正数时,index值是从0开始计算的。

      1.5:push()

      push方法用于在数组的末端添加一个或多个元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组

        var arr = [1,2,3,4,5];
    
        arr.push(6);
        console.log(arr);    // [1, 2, 3, 4, 5, 6]
        arr.push([7,8]);
        console.log(arr);    // [1, 2, 3, 4, 5, 6, [7, 8]]
        arr.push(true);
        console.log(arr);    // [1, 2, 3, 4, 5, 6, [7, 8], true]

      1.6:实例方法习题

      ★数组中去掉最大值,去掉最小值,其余元素进行相加。

        function sumArray(array) {
            if (array === null || array.length < 2) {
                return 0;
            } else {
                array = array.sort(function(a, b) {
                    return a - b;
                })
                var sum = 0;
                for (var i = 1; i < array.length - 1; i++) {
                    sum += array[i];
                }
                return sum;
            }
        }
    
        console.log(sumArray([1,2,3,4,5,9]));    //14

      上面代码中,使用了sort方法对数组进行排序。然后巧妙地使用for循环,让变量初始化的值等于第二个元素,让循环的长度值等于数组的长度减一,这样就实现了去掉一个最小值和最大值,剩余值进行相加的方法。

      ★将字符串中的元素分隔,首字符大写,然后再按照index值加入相同小写字母。比较难描述,看例子,就很容易理解。

     1     function accum(s) {
     2         var arr = s.split('');
     3         return arr.map(function(value, index) {
     4             var upper = value.toUpperCase();
     5             for (var i = 1; i <= index; i++) {
     6                 upper += value.toLowerCase();
     7             }
     8             return upper;
     9         }).join('-')
    10     }
    11 
    12     console.log(accum('keith'));    //'K-Ee-Iii-Tttt-Hhhhh'
    13     console.log(accum('studyhard'));    //'S-Tt-Uuu-Dddd-Yyyyy-Hhhhhh-Aaaaaaa-Rrrrrrrr-Ddddddddd'

      上面代码中,使用字符串对象的实例方法先将字符串分割,接着用map方法循环每一个字符。要注意的是map方法会返回一个新数组,不改变原数组,最后使用字符串对象实例方法join方法将字符串以'-'的形式分割。

      ★将平均数与个人成绩进行比较。如果大于平均数,则返回true;否则为false。

     1     function betterThanAverage(classPoints, yourPoints) {
     2         var len=classPoints.length;
     3         var sum=0;
     4         for (var i = 0; i < classPoints.length; i++) {
     5             sum+=classPoints[i];
     6         }
     7         if (yourPoints>(sum/len)) {
     8             return true;
     9         } else{
    10             return false;
    11         }
    12     }
    13 
    14     console.log(betterThanAverage([62,83,74,66,99,100],80));    //false

      上面代码中,先获取数组的长度,然后将数组进行相加,再除以长度值,最后进行比较。

      ★当数组中的数为正数时,计算正数的个数;当数组中的数为负数时,将所有负数相加。注意,对负数和正数的处理方式不同。

        function countPositivesSumNegatives(input) {
         if (input===null||input.length===0) {
                return [];
            } else{
                var count = 0;
                var sum = 0;
                for(var i = 0;i < input.length; i++){
                    if (input[i]<0) {
                        sum+=input[i];
                    } else if(input[i]!==0){
                        count+=1;
                    }
                }
                return [count,sum];
            }
        }
    
        console.log(countPositivesSumNegatives([1, 2, 3, 4, 5, 6, 7, 8, 9, 131,10, -11, -12, -13, -14, -15]));    //[11, -65]

      上面代码中,对数组进行了简单的判断。使用for循环再对数组的正负值进行判断。

      ★创建一个函数,这个函数有2个参数,第一个参数为有x个值得数组,第二个参数为数组的长度。功能就是将最后x个值进行相加然后传入数组末尾。有两种解决方法,第二种方法采用了es6的方法箭头函数。同样,看实例比较容易理解题目的意思。

        function Sum(first,last){
            return first+last;
        }
    
        function Xbonacci(signature,n){
            var indexArr = signature.length;
            for (var i = 0; i < n - indexArr; i++) {
                var sum = signature.slice(-indexArr).reduce(Sum);
                signature.push(sum);
            }
            return signature.slice(0,n);
        }
    
        console.log(Xbonacci([0,0,0,0,1],10));    //[0, 0, 0, 0, 1, 1, 2, 4, 8, 16]
        console.log(Xbonacci([1,1],10));    // [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
        console.log(Xbonacci([1,0,0,0,0,0,1],10));    // [1, 0, 0, 0, 0, 0, 1, 2, 3, 6]
        console.log(Xbonacci([0, 19, 16, 3, 6, 14, 17, 14, 15, 20, 8, 19, 7, 8, 12, 14, 11, 11, 18],4)); // [0, 19, 16, 3]
        const Xbonacci = (sig, n) => {
          let len = sig.length;
          for (let i = len; i < n; i++) 
            sig[i] = sig.slice(i - len).reduce((a, b) => a + b);
          return sig.slice(0, n);
        }

      上面代码中,将[0,0,0,0,1]相加得2,然后将2push到数组中;将[0,0,0,1,2]相加4,然后将4push到数组中,以此类推。最后返回处理后的数组。

      个人认为,熟悉数组实例方法最好的办法就是去尝试做这些题目,每一次做的题目对数组的方法都会有一个新的理解,每一次理解都会让你意识到哪一个方法需要在哪一种场景使用,而哪一个方法在某个场景使用是不合适的。光看不练对知识的掌握程度总是稍显不足。

    2.数组方法的扩展

      数组的实例方法中,没有给我们提供数组求和,求平方,求立方,求平均数,求偶数元素,求奇数元素的方法。所以我们需要去扩展数组的方法以方便实际工作中的开发。

        Array.prototype.square  = function () { return this.map(function(n) { return n*n; }); }
        Array.prototype.cube    = function () { return this.map(function(n) { return n*n*n; }); }
        Array.prototype.average = function () { return this.sum() / this.length; }
        Array.prototype.sum     = function () { return this.reduce(function(a, b) { return a + b; }, 0); }
        Array.prototype.even    = function () { return this.filter(function(item) { return 0 === item % 2; }); }
        Array.prototype.odd     = function () { return this.filter(function(item) { return 0 !== item % 2; }); }
    
        var arr = [1,2,3,4,5,6];
    
        console.log(arr.square());    // [1, 4, 9, 16, 25, 36]
        console.log(arr.cube());    // [1, 8, 27, 64, 125, 216]
        console.log(arr.average());    // 3.5
        console.log(arr.sum());        // 21
        console.log(arr.even());    // [2, 4, 6]
        console.log(arr.odd());        // [1, 3, 5]

      上面代码中,为构造函数Array的原型对象添加square,cube等方法的目的是让所有实例都可以共享这些方法。而prototype属性的作用也就是让所有实例对象可以共享属性和方法。  

      如果想理解数组方法的扩展,需要知道的知识有:

      1.原型对象和构造函数的关系。

      2.this关键字的指向性问题。

      如果想要详细了解,可以前往这这些文章。Javascript中prototype属性的详解javascript之 this 关键字详解Javascript 中构造函数与new命令的密切关系深入理解Javascript中构造函数和原型对象的区别 等。

      

    完。

    感谢大家的阅读。

    转载请注明出处:http://www.cnblogs.com/Uncle-Keith/p/5846576.html

  • 相关阅读:
    MVP社区巡讲照片集
    周末之个人杂想(十六)
    SQL Server 2014 BI新特性(二)结合Data Explorer和GeoFlow进行数据分析
    SQL Server 2014 BI新特性(一)五个关键点带你了解Excel下的Data Explorer
    Tabular Model下的ADOMD.NET
    玩玩Excel下的Power View
    LeakCanary,30分钟从入门到精通
    Android热修复技术总结
    阿里最新热修复Sophix与QQ超级补丁和Tinker的实现与总结
    热修复——深入浅出原理与实现
  • 原文地址:https://www.cnblogs.com/unclekeith/p/5846576.html
Copyright © 2011-2022 走看看