C#函数式编程中的标准高阶函数详解
作者:junjie 发布时间:2021-06-09 06:27:07
何为高阶函数
大家可能对这个名词并不熟悉,但是这个名词所表达的事物却是我们经常使用到的。只要我们的函数的参数能够接收函数,或者函数能够返回函数,当然动态生成的也包括在内。那么我们就将这类函数叫做高阶函数。但是今天我们的标题并不是高阶函数,而是标准高阶函数,既然加上了这个标准,就意味着在函数式编程中有一套标准的函数,便于我们每次调用。而今天我们将会介绍三个标准函数,分别为Map、Filter、Fold。
Map
这个函数的作用就是将列表中的每项从A类型转换到B类型,并形成一个新的类型。下面我们可以看看在FCSLib中是如何实现的:
相信很多人应该都能够看懂这段代码,仅仅只是循环list数据。然后调用convert函数转换,最后通过yield将其组成一个列表返回。下面我们通过一个简单的例子来演示下如何使用这个标准高阶函数:
我们通过声明了一个数组data,然后利用map函数将其中的ID提取出来,单独形成一个列表。
Filter
通过名字应该能够猜出他大概的含义了,就是用来过滤数据的。相信一些人能够根据上面写出这个标准高阶函数的具体实现,当然这里不管读者有没有写出,我们都来看看FCSLib中是如何实现的:
这里我们只是少了一个泛型参数,对应的第一参数的是能够接收T类型返回bool类型的函数(Predicate也是.NET自带的,可能我们用惯了Func和Action,并且利用Func<T,bool>也可以实现一样的效果。),而语句主要是在循环后调用了predicate去判断是否满足条件,如果满足条件则返回。
Fold
这个标准高阶函数可能会比较难,因为它分为了左折叠和右折叠两种。接收的参数有三个,分别是起始值,累加函数,列表。大致的执行过程就是在第一次调用我们的累加函数时将起始值作为一个参数,而列表中的第一个值作为第二个参数去调用我们的累加函数,累加函数计算出结果,而这个结果将作为下一次调用累加函数时的第一参数,而第二个参数则是列表中的下一项,以此类推。所以通过这个高阶函数我们可以直接计算出列表中每项数据累加后的结果,而在FCSLib中的具体实现则如下所示:
通过查看源代码我们也可以得出之前的执行流程,在第一次的时候v的值为startValue,而之后就会将accmulator函数的返回值保存进v,这样下一次执行accmulator时就作为第一个参数传入。下面我们通过一个简单的例子来看看如何使用:
左折叠完成之后对应的还有一个右折叠,当然根据名字也可以猜出。就是从list的末尾开始进行循环,所以我们可以这样来实现FoldR:
这里还要指出的就是左折叠和右折叠是最常用的算法之一,他完全可以实现像我们之前介绍过的Map和Filter,而只要按照下面这种方式写即可:
这里我们就是利用Fold函数的一个特性来实现的,因为累加函数每次都会将上一次计算得出的结果传递给下一个累加函数(new List<R>()我们直接将其作为起始值传入),最后我们都会通过return x将这个列表返回,这样下一次再调用这个累加函数之后x依然是同一个列表。对应的还有Filter的实现:
而具体的调用方式则和Map,Filter是一致的,并没有什么特别大的区别。
关于Linq中的Map、Filter和Fold
其实函数式编程已经在不知不觉中慢慢的进入到我们的生活中,其实我们经常在Linq中使用的select、where和aggregate就是对应着函数式编程中的map、filter和fold。
猜你喜欢
- 本次主要分享的是3个免费的二维码接口的对接代码和测试得出的注意点及区别,有更好处理方式多多交流,相互促进进步;最近在学习JavsScript
- 本文介绍了struts2的国际化实现网站整体中英文切换实例代码,分享给大家,具体如下:环境要求:Struts2框架环境搭建成功为了实现程序的
- springboot用以进行web项目开发的便捷性,本文不再赘述,主要是想将工作中基于springboot与gradle的多模块项目的构建经
- 到底什么是反射呢???反射的核心就是JVM在运行时才动态加载类或调用方法,访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。每
- 本文为大家分享的java算法计算阶乘,在学习Java课程时经常会遇到求阶乘问题,今天接跟大家一起探讨一下代码如下:package com.x
- 网页爬虫:其实就是一个程序用于在互联网中获取符合指定规则的数据。package day05; import java.io.Buffered
- 简介本文用示例介绍使用MyBatis-Plus进行多表查询的方法,包括静态查询和动态查询。代码controllerpackage com.e
- DAO模式是接口的一个典型应用。1. StudenDaoListImpl.java与StudentDaoArrayImpl.java有何不同
- 在上篇文章给大家介绍了FastDFS安装和配置整合Nginx-1.13.3的方法,大家可以点击查看下。今天使用Java代码实现文件的上传和下
- 官网文档背景项目A中需要多数据源的实现,比如UserDao.getAllUserList() 需要从readonly库中读取,但是UserD
- 本文实例为大家分享了Java实现扑克牌程序的具体代码,供大家参考,具体内容如下思路:在实现之前,先要想好步骤,思路清晰才不会出错。要实现一副
- 四大函数式接口新时代的程序员:lambda 表达式,链式编程,函数式接口,Stream 流式计算函数式接口: 只有一个方法的接口@Funct
- 引言思考:HashTable是线程安全的,为什么不推荐使用?HashTable是一个线程安全的类,它使用synchronized来锁住整张H
- 前言本文主要跟大家介绍了关于Java用gson解析Json的相关内容,分享出来供大家参考学习,需要的朋友们下面来一起看看吧。json数据{&
- 使用匿名内部类课使代码更加简洁、紧凑,模块化程度更高。内部类能够访问外部内的一切成员变量和方法,包括私有的,而实现接口或继承类做不到。然而这
- 不同点:不能直接实例化接口。接口不包含方法的实现。接口可以多继承,类只能单继承。类定义可以在不同的源文件之间进行拆分。相同点:接口、类和结构
- 问题说明:IDEA编译的时候乱码,Build Output提示信息乱码�����。解决方案一:将Help—>Edit Cusuom V
- 本文实例讲述了java数据结构与算法之noDups去除重复项算法。分享给大家供大家参考,具体如下:public static void no
- 这篇文章主要介绍了Spring如何在一个事务中开启另一个事务,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需
- 一、BufferedImage类介绍生成验证码图片主要用到了一个BufferedImage类,如下:创建一个DrawImage Servle