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

  

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

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • oracle hint中ordered 和leading原理很好的帖子

    oracle hint中ordered 和leading原理很好的帖子问题 请教 HINT 写法我有一个 SQL 添加如下 hint 目的是指定 hash join 方式 select ordereduse hash a b c d Froma b c dWhere 其中 nbsp nbsp nbsp nbsp a 只与 b 有关联关系 b 只与 c 有关联关系 b 只与 c 有关联关系 c 只与 d 有关联关系 nbsp nbsp 数量级 a 1000 条 nbsp nbsp b 100

    2025年7月4日
    3
  • 前端VSCode常用插件「建议收藏」

    前端VSCode常用插件「建议收藏」前端VSCode常用插件1.Chinese(Simplified)vscode下载完毕是英文版的,先安装这个插件,改为中文版,所以是我们第一个安装的插件。2.AutoRenameTag修改开始标签,结束标签跟着自动变化,比较好用。3.OneDarkPro颜色主题4.格式化代码(vscode系统自带)但是html标签嵌套比较多,可能需要自动格式化比较好,所以我们可以利用vscode自动的功能格式化代码,暂且不用格式化插件,自动保存照样能格式化代…

    2022年7月25日
    8
  • java迭代和 递归的异同_递归和迭代有什么区别?简述区别

    java迭代和 递归的异同_递归和迭代有什么区别?简述区别你对于递归和迭代都了解吗?那么你是否知道递归和迭代的区别呢?那么下面就和小编一起来了解一下,这两者之间的区别究竟是怎样的吧!一、递归和迭代区别首先我们要讲到的就是两者之间的概念。首先,程序调用自身的编程技巧叫做递归,函数自己调用自己。一个函数在它的定义当中,直接或者是间接的调用自身的一种方法。它经常将一个大型的复杂的问题转化为一个和原来的问题相似的但是规模较小的问题来解决。这样能够极大的减小代码量…

    2022年5月3日
    52
  • shell循环打印「建议收藏」

    shell循环打印「建议收藏」#!/usr/bin/envbashstart=”$1″end=”$2″while[${start}-le${end}]doecho”${start}”start=$((${start}+1))donewhile[${start}-le${end}];doecho”${start}”start=$((${start}+1))do…

    2022年7月24日
    11
  • 矩阵相乘详解

    矩阵相乘详解首先要知道矩阵是怎么相乘的首先,两个矩阵要是想相乘需要满足,第一个矩阵的列数等于第二个矩阵的行数满足的话就可以相乘得到新的矩阵了举个例子嗷:矩阵a:123322212矩阵b:223121a矩阵是3*3(3行3列)的矩阵,b矩阵是3*2(3行2列)的矩阵,满足第一个矩阵的列数等于第二个矩阵的行数。那我们就可以相乘了一个m*n的矩阵和一个…

    2022年6月28日
    29
  • Python 读取txt文件

    Python 读取txt文件1.首先将数据加载到Python中,看需要做哪些处理。2、从显示的内容可以看出,两个数字之间是以空格,作为分隔符,这里读成一行了。使用sep=””处理,打印查看效果。3、使用分隔符后,分成了三列。但是还有一个问题,第一行被当成了表头,解决方法:使用names=[]给每列命名~ok啦,现在可以实现读取txt文件的任务了~…

    2022年5月30日
    58

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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