zoukankan      html  css  js  c++  java
  • 《JS权威指南学习总结--8.8 函数式编程和8.8.1使用函数处理数组》

    内容要点:

       和Lisp、Haskell不同,JS并非函数式编程语言,但在JS中可以像操控对象一样操控函数,

      也就是说可以在JS中应用函数式编程技术。ES5中的数组方法(诸如map()和reduce())就可以非常适用于函数式编程风格。

    一.使用函数处理数组

       假设有一个数组,数组元素都是数字,我们想要计算这些元素的平均值和标准差。

       若用非函数式编程风格的话,代码是这样:

            var data = [1,1,3,5,5]; //这里是待处理的数组

           //平均数是所有元素的累加和值除以元素个数

            var total = 0;

            for(var i=0;i<data.length;i++) total +=data[i];

            var mean = total/data.length; //平均数是3

          //计算标准差,首先计算每个数据减去平均数之后偏差的平方然后求和

            total = 0;

            for(var i=0;i<data.length;i++){

                 var deviation = data[i] - mean;

                total +=deviation*deviation;

             }

            var stddev = Math.sqrt(total/(data.length-1)); //标准差的值是2

          可以使用数组方法map()和reduce()来实现同样的计算,

              //首先定义两个简单的函数

               var sum = function(x,y){ return x+y; };

               var square = function(x){ return x*x; };

             //然后将这些函数和数组方法配合使用计算平均数和标准差

               var data = [1,1,3,5,5];

               var mean = data.reduce(sum)/data.length;

               var deviations = data.map(function(x){ return x-mean; });

               var stddev = Math.sqrt(deviations.map(square).reduce(sum)/(data.length-1));

               console.log(mean); //3
               console.log(deviations); //[-2,-2,0,2,2]
               console.log(deviations.map(square));//[4, 4, 0, 4, 4]
               console.log(deviations.map(square).reduce(sum)); //16
               console.log(stddev); //2

             ES3并不包含这些数组方法,如果不存在内置方法的话我们可以自定义map()和reduce()函数

                //对于每个数组元素调用函数f(),并返回一个结果数组。如果Array.prototype.map定义了的话,就使用这个方法。

                  var map = Array.prototype.map

                                 ?  function(a,f){ return a.map(f); }

                                 :   function(a,f){

                                         var result = [];

                                          for(var i =0,len=a.length;i<len;i++){

                                              if(i in a) results[i] = f.call(null,a[i],i,a);

                                     }

                                       return result;

                                  };

                   //使用函数f()和可选的初始值将数组a减至一个值,如果Array.prototype.reduce存在的话,就使用这个方法

                     var reduce = Array.prototype.reduce

                                        ? function(a,f,initial){   //如果reduce()方法存在的话

                                        if(arguments.length>2)

                                               return a.reduce(f,initial); //如果传入了一个初始值

                                               else return a.reduce(f); //否则没有初始值 

                                             }

                                          :function(a,f,initial){   //这个算法来自ES5规范

                                              var i =0,len = a.length,accumulator;

                                              //以特定的初始值开始,否则第一个值取自a

                                               if(arguments.length>2) accumulator = initial;

                                               else{

                                                      if(len ==0) throw TypeError();

                                                       while(i<len){

                                                              if(i in a){

                                                                    accumulator = a[i++];

                                                                     break;

                                                                 }

                                                                else i++;

                                                        }

                                                       if(i==len)  throw TypeError();

                                                 }

                                            //对于数组中剩下的元素依次调用f()

                                            while(i<len){

                                                 if(i in a)  accumulator = f.call(undefined,accumulator,a[i],i,a);

                                                 i++;                        

                                              }

                                              return accumulator;

                                     };

          使用定义的map()和reduce()函数,计算平均值和标准差的代码:

                var data = [1,1,3,5,5];

                var sum = function(x,y){ return x+y; };

                var square = function(x,y){ return x*y; };       

                var mean = reduce(data,sum)/data.length;

                var deviations = map(data,function(x){ return x-mean; });      

                var  stddev = Math.sqrt(reduce(map(deviations,square),sum)/(data.length-1));

  • 相关阅读:
    打印九九乘法表
    PAT (Basic Level) Practice (中文) 1091 N-自守数 (15分)
    PAT (Basic Level) Practice (中文)1090 危险品装箱 (25分) (单身狗进阶版 使用map+ vector+数组标记)
    PAT (Basic Level) Practice (中文) 1088 三人行 (20分)
    PAT (Basic Level) Practice (中文) 1087 有多少不同的值 (20分)
    PAT (Basic Level) Practice (中文)1086 就不告诉你 (15分)
    PAT (Basic Level) Practice (中文) 1085 PAT单位排行 (25分) (map搜索+set排序+并列进行排行)
    PAT (Basic Level) Practice (中文) 1083 是否存在相等的差 (20分)
    PAT (Basic Level) Practice (中文) 1082 射击比赛 (20分)
    PAT (Basic Level) Practice (中文) 1081 检查密码 (15分)
  • 原文地址:https://www.cnblogs.com/hanxuming/p/5831180.html
Copyright © 2011-2022 走看看