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

  

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

一只想要飞得更高的小菜鸟
目录
相关文章
|
2月前
|
算法 JavaScript 前端开发
第一个算法项目 | JS实现并查集迷宫算法Demo学习
本文是关于使用JavaScript实现并查集迷宫算法的中国象棋demo的学习记录,包括项目运行方法、知识点梳理、代码赏析以及相关CSS样式表文件的介绍。
第一个算法项目 | JS实现并查集迷宫算法Demo学习
|
1月前
|
前端开发 算法 JavaScript
无界SaaS模式深度解析:算力算法、链接力、数据确权制度
私域电商的无界SaaS模式涉及后端开发、前端开发、数据库设计、API接口、区块链技术、支付和身份验证系统等多个技术领域。本文通过简化框架和示例代码,指导如何将核心功能转化为技术实现,涵盖用户管理、企业店铺管理、数据流量管理等关键环节。
|
3月前
|
JavaScript 算法 前端开发
JS算法必备之String常用操作方法
这篇文章详细介绍了JavaScript中字符串的基本操作,包括创建字符串、访问特定字符、字符串的拼接、位置查找、大小写转换、模式匹配、以及字符串的迭代和格式化等方法。
JS算法必备之String常用操作方法
|
3月前
|
JavaScript 算法 前端开发
JS算法必备之Array常用操作方法
这篇文章详细介绍了JavaScript中数组的创建、检测、转换、排序、操作方法以及迭代方法等,提供了数组操作的全面指南。
JS算法必备之Array常用操作方法
|
3月前
|
算法 JavaScript 前端开发
国标非对称加密:RSA算法、非对称特征、js还原、jsencrypt和rsa模块解析
国标非对称加密:RSA算法、非对称特征、js还原、jsencrypt和rsa模块解析
276 1
|
3月前
|
JavaScript 算法 前端开发
"揭秘Vue.js的高效渲染秘诀:深度解析Diff算法如何让前端开发快人一步"
【8月更文挑战第20天】Vue.js是一款备受欢迎的前端框架,以其声明式的响应式数据绑定和组件化开发著称。在Vue中,Diff算法是核心之一,它高效计算虚拟DOM更新时所需的最小实际DOM变更,确保界面快速准确更新。算法通过比较新旧虚拟DOM树的同层级节点,递归检查子节点,并利用`key`属性优化列表更新。虽然存在局限性,如难以处理跨层级节点移动,但Diff算法仍是Vue高效更新机制的关键,帮助开发者构建高性能Web应用。
71 1
|
28天前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。
|
13天前
|
算法 数据挖掘 数据安全/隐私保护
基于FCM模糊聚类算法的图像分割matlab仿真
本项目展示了基于模糊C均值(FCM)算法的图像分割技术。算法运行效果良好,无水印。使用MATLAB 2022a开发,提供完整代码及中文注释,附带操作步骤视频。FCM算法通过隶属度矩阵和聚类中心矩阵实现图像分割,适用于灰度和彩色图像,广泛应用于医学影像、遥感图像等领域。
|
14天前
|
算法 调度
基于遗传模拟退火混合优化算法的车间作业最优调度matlab仿真,输出甘特图
车间作业调度问题(JSSP)通过遗传算法(GA)和模拟退火算法(SA)优化多个作业在并行工作中心上的加工顺序和时间,以最小化总完成时间和机器闲置时间。MATLAB2022a版本运行测试,展示了有效性和可行性。核心程序采用作业列表表示法,结合遗传操作和模拟退火过程,提高算法性能。
|
15天前
|
存储 算法 决策智能
基于免疫算法的TSP问题求解matlab仿真
旅行商问题(TSP)是一个经典的组合优化问题,目标是寻找经过每个城市恰好一次并返回起点的最短回路。本文介绍了一种基于免疫算法(IA)的解决方案,该算法模拟生物免疫系统的运作机制,通过克隆选择、变异和免疫记忆等步骤,有效解决了TSP问题。程序使用MATLAB 2022a版本运行,展示了良好的优化效果。