js算法初窥06(算法模式03-函数式编程)
在解释什么是函数式编程之前,我们先要说下什么是命令式编程,它们都属于编程范式的一种。命令式编程其实就是一块一块的代码,其中包括了我们要执行的逻辑或者判断或者一些运算。也就是按部就班的一步一步完成我们所需要的逻辑。而函数式编程则是类似于一个函数一个函数的调用。我们来看代码,更清晰的理解一下函数式编程与命令式编程的区别。
//这是命令式
var printArray = function (array) {
for (var i = 0; i < array.length; i++) {
console.log(array[i])
}
}
printArray([1,2,3,4,5]);
//函数式
var forEach = function (array,action) {
for (var i = 0; i < array.length; i++) {
action(array[i])
}
} var logItem = function (item) {
console.log(item)
} forEach([2,3,4,5,6],logItem)
我们先来看看上面的代码做了什么——“遍历数组,然后打印数组的每一项”。在命令式编程中,我们一步一步的完成了这句话。先遍历数组,然后打印每一项元素。那么我们再来看函数式编程,我们先声明了两个函数,一个是遍历数组元素的forEach(这里的action参数其实就是一个回调函数),一个是打印每一项的logItem。我们把每一步骤的需要操作的逻辑都用函数来区分开,最后再调用函数来执行运算。
在有了ES6之后,我们可以更加方便的用函数式编程范式来编写我们的代码,下面我们再来看一个例子。
//找出数组中元素最小的值
//代码十分简单,我们假设数组的第一个元素是最小的并赋值给minVal变量
//遍历除第一项元素以外的所有数组内元素并与minVal比较,如果当前的minVal比array[i]还要大,那么就把minVal替换成array[i];
//最后返回结果
var findMinValInArray = function (array) {
var minVal = array[0];
for (var i = 1; i < array.length; i++) {
if(minVal > array[i]) {
minVal = array[i];
}
}
return minVal;
}
console.log(findMinValInArray([7,8,9,5,31,2]));
//那么我们其实可以更简单的实现上面的方法,比如Math.min以及解构操作符(...)
const _min = function (array) {
return Math.min(...array);
}
console.log(_min([5,6,9,3,1]));
//我们还可以用ES6的箭头函数,让我们的代码更好看一些。
const min = arr => Math.min(...arr);
console.log(min([2,3,9,4,8]))
上面代码中Math.min是一个方法,返回参数中的最小值,参数可以是无限个。那么还有ES6的箭头函数以及扩展运算符(...)。这里不做详细的解释,附上连接地址,大家可以更为详细的知道什么是箭头函数以及扩展运算符。
那么,接下来我们看看如何利用我们前面已经学过的数组方法来让我们的代码更加“函数式”。
//我们先看一个命令式编程的例子
var daysOfWeek = [
{name:"Monday",value:1},
{name:"Tuesday",value:2},
{name:"Wednesday",value:7},
]
var daysOfWeekValues_ = [];
for (var i = 0; i < daysOfWeek.length; i++) {
daysOfWeekValues_.push(daysOfWeek[i].value);
} //再来看看函数式编程的样子
var daysOfWeekValues = daysOfWeek.map(function (day) {
//这个day其实就是数组中的每一项,具体可以去我前面的文章查看map的参数
return day.value;
})
console.log(daysOfWeekValues); //我们还可以使用filter来过滤一个数组的值。
//比如:
//命令式
var positiveNumbers_ = function (array) {
var positive = [];
for (var i = 0; i < array.length; i++) {
if(array[i] >= 0) {
positive.push(array[i]);
}
} return positive;
}
console.log(positiveNumbers_([-1,2,1,-2]));
//函数式
var positiveNumbers = function (array) {
return array.filter(function (num) {
return num >= 0;
})
} console.log(positiveNumbers([1,2,-1,-2,-5])); //我们再来看看reduce函数
//命令式
var sumValues = function (array) {
var total = array[0];
for (var i = 1; i < array.length; i++) {
total += array[i];
}
return total;
}
console.log(sumValues([1,2,3,4,5]));
//函数式
var sum_ = function (array) {
return array.reduce(function (a,b) {
return a + b;
})
} console.log(sum_([1,2,3,4,5]))
//我们还可以用ES6的方法改进一下
var sum = arr => arr.reduce((a,b) => a + b);
console.log(sum([1,2,3,4,5]))
上面我们看了一些函数式编程的例子,代码都不复杂,很容易理解。所以就没做详细的注释。那么我们下面再看最后一个有趣的例子。
//我们来用命令式编程实现一个二维数组合并为一维数组的方法
var mergeArrays_ = function (arrays) {
var count = arrays.length,
newArray = [],
k = 0; for (var i = 0; i < count; i++) {
for (var j = 0; j < arrays[i].length; j++) {
newArray[k++] = arrays[i][j];
}
}
return newArray;
} console.log(mergeArrays_([[1,2,3],[4,5],[6]])); //我们最后再看看函数式的写法
var mergeArraysConcat = function (arrays) {
return arrays.reduce(function (p,n) {
return p.concat(n);
})
};
console.log(mergeArraysConcat([[1,2,3],[4,5],[6],[7]])) //我们再来看看牛逼的方法
const mergeArrays = (...arrays) => [].concat(...arrays);
console.log(mergeArrays([1,2,3],[4,5],[6],[7],[8]));
//这一行代码需要解释下。我们来看看(...arrays)会变成什么
console.log(...[[1,2,3],[4,5],[6],[7],[8]])//一个一个单独的数组
//然后我们再用一个空数组去合并参数中的每一个单独的数组就可以了
到这里我们函数式编程的简单讲解就结束了,上面的内容其实不过万分之一,希望能让大家对代码的编写打开了另一扇窗户,其实函数式编程在我们的实际工作中也是极为有用的。希望大家可以认真对待和学习,最后,附上一个可以学习函数式编程的网址:http://reactivex.io/learnrx/。这是一个外国的练习网站,只要会简单的英语看下来应该是没有问题的。
最后,由于本人水平有限,能力与大神仍相差甚远,若有错误或不明之处,还望大家不吝赐教指正。非常感谢!
js算法初窥06(算法模式03-函数式编程)的更多相关文章
- js算法初窥05(算法模式02-动态规划与贪心算法)
在前面的文章中(js算法初窥02(排序算法02-归并.快速以及堆排)我们学习了如何用分治法来实现归并排序,那么动态规划跟分治法有点类似,但是分治法是把问题分解成互相独立的子问题,最后组合它们的结果,而 ...
- js算法初窥01(排序算法01-冒泡、选择、插入)
排序,我想大家一定经历过或者正在经历着.或许你不懂算法,对排序算法一无所知,但是你一定用过一些第三方库的api来一键排序,那么,在你享受便捷的同时,你是否想过它的底层是如何实现的?这样的算法实现方式是 ...
- Python <算法思想集结>之初窥基础算法
1. 前言 数据结构和算法是程序的 2 大基础结构,如果说数据是程序的汽油,算法则就是程序的发动机. 什么是数据结构? 指数据在计算机中的存储方式,数据的存储方式会影响到获取数据的便利性. 现实生活中 ...
- js算法初窥03(简单搜索及去重算法)
前面我们了解了一些常用的排序算法,那么这篇文章我们来看看搜索算法的一些简单实现,我们先来介绍一个我们在实际工作中一定用到过的搜索算法--顺序搜索. 1.顺序搜索 其实顺序搜索十分简单,我们还是以第一篇 ...
- js算法初窥03(搜索及去重算法)
前面我们了解了一些常用的排序算法,那么这篇文章我们来看看搜索算法的一些简单实现,我们先来介绍一个我们在实际工作中一定用到过的搜索算法——顺序搜索. 1.顺序搜索 其实顺序搜索十分简单,我们还是以第一篇 ...
- js算法初窥04(算法模式01-递归)
终于来到了有点意思的地方--递归,在我最开始学习js的时候,基础课程的内容就包括递归,但是当时并不知道递归的真正意义和用处.我只是知道,哦...递归是自身调用自身,递归要记得有一个停止调用的条件.那时 ...
- js算法初窥02(排序算法02-归并、快速以及堆排序)
上一篇,我们讲述了一些简单的排序算法,其实说到底,在前端的职业生涯中,不涉及node.不涉及后台的情况下,我目前还真的没想到有哪些地方可以用到这些数据结构和算法,但是我在前面的文章也说过了.或许你用不 ...
- js算法初窥07(算法复杂度)
算法复杂度是我们来衡量一个算法执行效率的一个度量标准,算法复杂度通常主要有时间复杂度和空间复杂度两种.时间复杂度就是指算法代码在运行最终得到我们想要的结果时所消耗的时间,而空间复杂度则是指算法中用来存 ...
- 如何编写高质量的 JS 函数(4) --函数式编程[实战篇]
本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/ZoXYbjuezOWgNyJKmSQmTw作者:杨昆 [编写高质量函数系列],往期精彩内容: ...
随机推荐
- caffe-win10-cifar10另
上一篇主要以bat形式实现了leveldb形式的cifar10,因为对于shell脚本不甚熟悉,所以这次专门利用.sh调用来实现lmdb形式的cifar10. 1.下载数据 同上一篇. 2.数据转换和 ...
- AT91RM9200---电源管理控制器(PMC)介绍
1.前言 PMC通过集成的两个OSC(一个主振荡器和一个慢时钟振荡器32.768khz)和两个PLLs产生系统所有的clock. PMC提供时钟给嵌入式处理器,并通过在IDLE模式下停止处理器时钟,直 ...
- sqlserver 无法获得数据库独占权
ALTER DATABASE trqxs_cs SET OFFLINE WITH ROLLBACK IMMEDIATE
- 转载:JAVA序列化与反序列化 (作者:YSOcean)
原文:https://www.cnblogs.com/ysocean/p/6870069.html File 类的介绍:http://www.cnblogs.com/ysocean/p/6851878 ...
- js学习、备忘
字符串使用单引号’abc’.(双引号也行.推荐:html→双引号,js→单引号)===严格等于.!==严格不等于if(x) 当x为undefined.null和0的时候都为false:需注意当x为0 ...
- 输入年月日判断是当年第几天(if判断)
- keras + tensorflow安装
先安装anaconda 一条指令:conda install keras 就可以把keras,tensorflow装好.
- windows下sublime通过sftp扩展上传文件到linux服务器上
首先在package controll下载sftp扩展,在任意磁盘下新建文件夹: 然后,添加该文件夹到sublime中,并在xhell中链接linux服务器,新建目录,mkdir /home/hel ...
- gcd,lcm
定理:gcd(a,b)*lcm(a,b)=a*b; 更相损减术:gcd(a,b)=gcd(b,a-b)=gcd(a,a-b) 欧几里得算法:gcd(a,b)=gcd(b,a mod b) 复杂度O(l ...
- 2017-2018-2 20155309 南皓芯 Exp9 Web安全基础
基础问题回答 1.SQL注入攻击原理,如何防御 原理:它是利用现有应用程序,将恶意的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入恶意SQL语句得到一个存在安全漏洞的网站上的数 ...