《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));
《JS权威指南学习总结--8.8 函数式编程和8.8.1使用函数处理数组》的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- shell -- yes or no
read -p "Do you want to .... [Y/N]? " yn while true; do case $yn in [Yy]|[Yy][Ee][Ss] ) br ...
- trove manual installation 翻译
目标 此文件提供了一步一步的指导手动安装trove在一个现有OpenStack的环境为了开发. 该文件将不包括: OpenStack的设置 trove服务配置 要求 正在运行的OpenStack的环境 ...
- dirty cow exp
公司搞底层的改了一下,说做到了几个不死机 /* * (un)comment correct payload first (x86 or x64)! * * $ gcc cowroot.c -o cow ...
- 驱动7段LED显示器
拿到7段LED显示器,先看看是共阴极还是共阳极,如果是共阳极,3和8接5V,5V串联一个220欧姆的电阻. 下面是购买的LED显示器的接线图例 5V串联电阻图例 下面为代码,此代码将实现在LED显示器 ...
- The APR based Apache Tomcat Native library tomcat启动错误
The APR based Apache Tomcat Native library which allows optimal performance in production environmen ...
- 【IE6的疯狂之七】样式中文注释后引发失效
这是IE6 出现的奇怪现象.这是由于css 和html 的编码不同所引致. 满足下面条件就会引起 注释下面的样式不起作用:1. css有中文注释2. css为ANSI编码3. html为utf-8编码 ...
- POJ 1952 BUY LOW, BUY LOWER
$dp$. 一开始想了一个$dp$做法,$dp[i][j]$表示前$i$个数字,下降序列长度为$j$的方案数为$dp[i][j]$,这样做需要先离散化然后用树状数组优化,空间复杂度为${n^2}$,时 ...
- MyBatis 学习-与 Spring 集成篇
根据官方的说法,在 ibatis3,也就是 Mybatis3 问世之前,Spring3 的开发工作就已经完成了,所以 Spring3 中还是没有对 Mybatis3 的支持.因此由 Mybatis 社 ...
- 在Eclipse中用TODO标签管理任务(Task)
Elipse为Java项目的时候,有一个很人性化的“任务管理”功能,利用这个功能可以方便地将项目中一些需要处理的任务记录下来.先来看看“任务管理”是怎么使用的吧.下面这个类在Class和name 属性 ...
- Python学习笔记——基础篇【第六周】——json & pickle & shelve & xml处理模块
json & pickle 模块(序列化) json和pickle都是序列化内存数据到文件 json和pickle的区别是: json是所有语言通用的,但是只能序列化最基本的数据类型(字符串. ...