C#函数式编程之序列
过了许久的时间,终于趁闲暇的时间来继续将函数式编程这个专辑连载下去,这段时间开头是为IOS这个新方向做准备,将OC的教程写成了SWIFT版,当然我个人是支持Xamarin,但是我一般会先掌握原生态的开发,再掌握Xamarin。后面剩下的时间开发了一个Xamarin App项目,用了十几天完成的。今天的内容将对比较简单,就是讲述如何利用函数式编程来实现列表推导。说的简单点就是列表的数据并不像我们平时开发那样实现写好的,而是通过一定的算法计算出来的(不是程序一打开就计算完成的,而是在使用的时候才计算的,并且只计算到我们使用的那一项为止)。
用函数方法实现迭代器
首先我们当然是先编写一个高阶函数来实现列表推导的主要功能部分,具体的代码如下所示:
public static IEnumerable<T> Sequence<T>(Func<T, T> getNext, T startVal, Func<T, bool> endReached)
{
if (getNext == null)
yield break;
yield return startVal;
T val = startVal;
while (endReached == null || !endReached(val))
{
val = getNext(val);
yield return val;
}
}
这个函数的作用就是根据一定的算法进行迭代,而这里利用了C# 2.0才有的语法。该函数首先是根据startVal开始迭代,并且根据getNext计算下一个值,而endReached则用来约束结束条件。所以我们可以看到如果endReached为NULL也是可行的,这样这个序列就是无穷的,当然不是死循环。下面我们利用一段简单的代码来掩饰如何使用这个函数:
static void Main(string[] args)
{
var oddNumbersForm1 = Sequence<int>(x => x + , , x => x >= );
foreach (int x in oddNumbersForm1)
{
Console.WriteLine(x);
}
Console.ReadKey();
}
最后我们在命令行界面中可以看到如下的显示:

值域
很多时候我们使用的序列都是很简单的,而利用上面的Sqquence函数则会变得复杂,同时这个函数还无法实现一些我们需要的功能,比如需要判断一个值时候存在范围中等等,所以我们下面将利用一个简单的Range来实现这些功能,当然内部还是使用的如上的Sequence函数,下面是具体的代码:
public class Range<T> : IEnumerable<T>
{
private T start;
private T end;
private Comparison<T> compare;
private IEnumerable<T> sequence; private static int Compare<U>(U one,U other)
{
return Comparer<U>.Default.Compare(one,other);
} public Range(T start, T end, Func<T, T> getNext, Comparison<T> compare)
{
this.start = start;
this.end = end;
this.compare = compare;
this.sequence = Sequence<T>(getNext, start, v => compare(getNext(v), end) > );
} public Range(T start, T end, Func<T, T> getNext)
: this(start, end, getNext, Compare) { } public IEnumerator<T> GetEnumerator()
{
return sequence.GetEnumerator();
} System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return ((IEnumerable<T>)this).GetEnumerator();
} public bool Contains(T value)
{
return compare(value, start) >= && compare(end, value) >= ;
}
}
通过上面的代码我们可以看到Range的功能远远比Sequence函数要强大的多,并且我们可以看到我们还提供了Contains方法用来判断指定的值是否在值域中,另外我们还可以获得IEnumerable借口的各种扩展方法供我们使用。
限制
有时我们的迭代器的实现可能很复杂,如果还要加上限制不仅仅会影响到其性能,同时还会导致代码的可读性较差,所以我们可以将这两者进行分离,负责生成序列的函数只需要没有任何限制,而将限制移转到外部,比如函数TFunc是一个返回序列的函数,并且没有限制,而CFunc则接受一个最大值,以及用来计算序列的函数,并且返回负责条件的序列,那么我们就可以像如下这样循环获取值:
foreach(int x in CFunc(,TFunc)){
Console.WriteLine(x);
}
至此关于函数式编程中的序列就结束了,后面的时间笔者将会抓紧时间尽快将这个专辑结束掉,开始集中在Xamarin.Android这个系列的教程上。
C#函数式编程之序列的更多相关文章
- C#函数式编程-序列
C#函数式编程之序列 过了许久的时间,终于趁闲暇的时间来继续将函数式编程这个专辑连载下去,这段时间开头是为IOS这个新方向做准备,将OC的教程写成了SWIFT版,当然我个人是支持Xamarin,但是我 ...
- python基础-函数式编程
python基础-函数式编程 高阶函数:map , reduce ,filter,sorted 匿名函数: lambda 1.1函数式编程 面向过程编程:我们通过把大段代码拆成函数,通过一层一层 ...
- Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程
Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程 这里的函数式编程的设计以muduo为例进行对比说明: Reactor实现架构对比 面向对象的设计类图如下: 函数式编程以muduo为例 ...
- python【6】-函数式编程
一.高阶函数 map,reduce 1.map() 函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回. def f(x): retur ...
- Atitit 函数式编程与命令式编程的区别attilax总结 qbf
Atitit 函数式编程与命令式编程的区别attilax总结 qbf 1.1. 函数式程序就是一个表达式.命令式程序就是一个冯诺依曼机的指令序列. 命令式编程是面向计算机硬件的抽象,有变量(对应着存 ...
- Python 函数式编程 & Python中的高阶函数map reduce filter 和sorted
1. 函数式编程 1)概念 函数式编程是一种编程模型,他将计算机运算看做是数学中函数的计算,并且避免了状态以及变量的概念.wiki 我们知道,对象是面向对象的第一型,那么函数式编程也是一样,函数是函数 ...
- Python入门笔记(21):Python函数(4):关于函数式编程的内建函数
一.关于函数式编程的内建函数 apply()逐渐被舍弃,这里不讨论 1.filter() #filter(func,seq) """纯Python描述filter函数&q ...
- Python基础:函数式编程
一.概述 Python是一门多范式的编程语言,它同时支持过程式.面向对象和函数式的编程范式.因此,在Python中提供了很多符合 函数式编程 风格的特性和工具. 以下是对 Python中的函数式编程 ...
- 简明python教程 --C++程序员的视角(九):函数式编程、特殊类方法、测试及其他
函数式编程 Lambda exec,eval和assert语句,repr函数 lambda语句 用来创建简短的单行匿名函数 print_assign = lambda name, value: n ...
随机推荐
- 非阻塞同步算法实战(二)-BoundlessCyclicBarrier
本人是本文的作者,首发于ifeve(非阻塞同步算法实战(二)-BoundlessCyclicBarrier) 前言 相比上一 篇而言,本文不需要太多的准备知识,但技巧性更强一些.因为分析.设计的过程比 ...
- service XXX does not support chkconfig
有时候为了方便管理,我们常常喜欢在Linux中将之安装为服务,然后就可以使用服务来管理. 但是当我们运行安装服务的命令时候,假设服务名为myservice #chkconfig --add myser ...
- 基于御安全APK加固的游戏反外挂方案
一. 前言 随着移动互联网的兴起,移动游戏市场近几年突然爆发,收入规模快速增长.根据第三方数据统计,国内移动游戏2015年市场规模已达514.6亿.由于手游市场强势兴起,而且后续增长势头会愈加猛烈.火 ...
- CSS自适应布局(包括两边宽度固定中间宽度自适应与中间宽度固定两边宽度自适应)
1.两边宽度固定,中间宽度自适应 (1)非CSS3布局,浮动定位都可以(以下用浮动) css样式: #left { float: left;width: 200px; background: lime ...
- 远程访问MySQL遇到的一些问题
一.access deny GRANT ALL PRIVILEGES ON *.* TO '用户名'@'IP地址' IDENTIFIED BY '密码' with grant option;
- Debian使用相关
1)将普通用户添加到sudo组 首先安装sudo: root@~#: apt-get install sudo 然后添加将wzc用户添加到sudo组: root@~#: usermod -a -G s ...
- springboot使用之三:springboot使用logback日志
springboot 默认使用的日志就是logback,所以使用logback不需要添加日志相关依赖了,执行 添加logback.xml配置文件,springboot这个聪明的框架便能识处理你的配置. ...
- 安装文件制作工具Wix概念快速入门
前言 Wix==Windows installer XML 顾名思议. 用于制作WINDOWS安装文件的XML格式的描述文件. 因为其实现方式为基于声明的方式,而非命令的方式. 特整理一下其相关的概念 ...
- Combination Sum II Combinations
https://leetcode.com/problems/combination-sum-ii/ 题目跟前面几道题很类似,直接写代码: class Solution { public: vector ...
- JavaSE自学笔记
ch03 [Thu Aug 18 2016 11:22:26 GMT+0800] 对象变量与对象之间是指代关系,对象变量并不能完全说明有无对象可用.这种指代关系是通过赋值运算建立起来的.对象变量保存的 ...