• 《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));

  • 相关阅读:
    [慢查优化]建索引时注意字段选择性 & 范围查询注意组合索引的字段顺序
    telnet报“Unable to connect to remote host:Connection refused”错误
    问题总结-2016
    vim保存文件时,生成.un~文件
    用uniq来处理文件重复数据--交集,差集,计数等(转)
    ThinkPHP的URL访问
    PHP中Exception异常
    Git Stash紧急处理问题,需要切分支
    git 命令学习
    gdb调试PHP扩展错误
  • 原文地址:https://www.cnblogs.com/hanxuming/p/5831180.html
Copyright © 2020-2023  润新知