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/。这是一个外国的练习网站,只要会简单的英语看下来应该是没有问题的。

  

  最后,由于本人水平有限,能力与大神仍相差甚远,若有错误或不明之处,还望大家不吝赐教指正。非常感谢!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/124411.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • android共享文件夹_安卓多用户共享文件

    android共享文件夹_安卓多用户共享文件AndroidN之前的Uri常规Uri有两种:媒体文件的Uri是content://,表示这是一个数据库数据。去数据库查询正常返回。其他的文件Uri是file://,表示这个是一个文件。这个uri是通过Uri.fromFile(Filefile)方法生成。AndroidN之前,这些uri可以传递到其他应用。AndroidN中共享文件Android

  • 简单的TCP客户端发包工具[通俗易懂]

    简单的TCP客户端发包工具[通俗易懂]一、TCP介绍先放这里有时间在写,最近在写DuiLib相关的使用内容,这部分大家凑活着看二、程序截图下载链接链接:https://pan.baidu.com/s/1MzNUzwd7WwBat6vNMcu6Ow密码:ibuv 主要源码://.h//TCPClient.cpp:定义应用程序的类行为。//#include"stdafx.h"#in…

  • HBase面试题总结1「建议收藏」

    HBase面试题总结1「建议收藏」hbase的特点是什么??1)hbase是一个分布式的基于列式存储的数据库,基于Hadoop的hdfs存储,zookeeper管理。2)hbase适合存储半结构化和非结构化数据,对于结构化数据字段不够确定或者杂乱无章很难按一个概念去抽取数据;3)hbase为空的纪录不会被存储;4)基于的表包含rowkey,时间戳,列族,新写入数据时,时间戳更新,同时可以查询到以前的版本;5)hbase是…

  • 最新dedecms 0day漏洞_易优cms漏洞

    最新dedecms 0day漏洞_易优cms漏洞原文地址:http://hi.baidu.com/artcracker/blog/item/682a1c24640ee37735a80f49.html 首先,我百度“NetCms网站管理系统”,然后顺手找了个网站。然后进去,/user/login.aspx    ,点注册。点击发表文章。在发表文章页面,点击“选择图片”  我们在这里,记下这个目

  • 费曼学习法

    费曼学习法费曼学习法我的理解:费曼学习法就是把学好的东西用简洁易懂的语言,传授给别人举例:你学完微积分,然后自己去培训班,自己做老师,传授给学生们,并且学生们都能听懂费曼学习法的四个步骤:1.确定目标

  • 运维堡垒机是什么_堡垒机一般怎么部署

    运维堡垒机是什么_堡垒机一般怎么部署在运维安全中,数据安全是重中之重,运维人员常常通过运维堡垒机进行服务器的日常维护工作,保证数据安全不受威胁。那么市面上的主流运维堡垒机都有哪些主要功能呢?1、单点登录功能堡垒机支持对X11、linux、unix、数据库、网络设备、安全设备等一系列授权账号进行密码的自动化周期更改,简化密码管理,让使用者无需记忆众多系统密码,实现与用户授权管理的无缝连接,这样可以通过对用户、角色、行为和资源的授权…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号