文档章节

PHP函数式编程初探之“三板斧”:过滤、映射、归约

暗夜在火星
 暗夜在火星
发布于 2016/11/20 15:59
字数 754
阅读 104
收藏 0

函数式编程是一种不同于对象式编程的思想,虽然PHP并不是天生就属于函数式编程的语言,也不擅长该领域,但这里希望通过PHP对函数式支持实现,加深对函数式编程的范式和思想。

 

PHP本身的语法、语义不能完全很好地支持函数式编程,因为这里我需要通过实现封装类库来完成PHP对函数式编程的支持。

 

两个示例的最终效果

先来看下最终的效果:假设我们需要计算1到5之间的偶数之和的两倍,那么:

$fun = new Functional_Lite(range(1, 5));


$rs = $fun->filter(function ($x) { return $x % 2 == 0;})
            ->map(function ($x) {return $x * 2;})
            ->reduce(function ($x, $y) { return $x + $y;}, 0);

var_dump($rs); // 2 * 2 + 4 * 2 = 12

 

如果想更简短一点,可以这样使用字符串表达式:

$fun = new Functional_Lite(range(1, 5));


$rs = $fun->filter('$it % 2 == 0')
            ->map('$it * 2')
            ->reduce('$it_1 + $it_2', 0);

var_dump($rs); // 2 * 2 + 4 * 2 = 12

注意这里使用了 $it 来表示每次迭代的元素;对于reduce操作,使用了$it_1、$it_2分别表示第一个元素、第二个元素。

 

除了对数值进行操作,我们也希望可以对字符串或其他类型的集合进行操作,假设需要过滤一个字符的单词,然后把剩下的单词转大写,再用空格拼接起来。那么:

$fun = new Functional_Lite(array('dogstar', 'x', 'love', 'y', 'yoyo', '!!'));

$rs = $fun->filter(function ($x) { return strlen($x) > 1;})
            ->map(function ($x) { return strtoupper($x);})
            ->reduce(function ($x, $y) { return $x . ' ' . $y;}, 'RS:');

var_dump($rs); // RS: DOGSTAR LOVE YOYO !!

在上面,对于最后的结果,我们在累加量初始了“RS:”,所以最后的结果里有“RS:”的前缀。这里的一个问题是,还没想好如何更好地处理初始值。

 

同样,使用字符串表达式,可以简化上面的处理以达到同样的效果:

$rs = $fun->filter('strlen($it) > 1')
            ->map('strtoupper($it)')
            ->reduce('$it_1 . " " . $it_2', 'RS:');

 

至此,通过上面两个示例,可以看出都使用了函数式编程的“三板斧”:过滤、映射、归约。

对于这“三板斧”的定义和作用,这里不作过多的赘述。

 

类库实现

上面,我们封装了Functional_Lite这个类,以便更好的实现函数式编程。为了构造一个函数式的类库,可以传入一个集合,目前只支持数组,且会忽略索引。具体的源代码,可见GIT仓库:http://git.oschina.net/dogstar/functional_php

 

小结

当然,这里只是简单地实现了一下函数式编程最主要的三个操作:过滤、映射、归约。但离函数式编程的道路还很遥远,比如柯里化、部分施用、偏函数、Either类、Opeion类、值不可变。而且还有很多在PHP是明显很难实现的,如上下文的处理。

Anyway,这只是一个小开始,只是作为自己的一个小结。

 

© 著作权归作者所有

共有 人打赏支持
暗夜在火星

暗夜在火星

粉丝 154
博文 163
码字总数 312957
作品 1
广州
程序员
向你老婆解释清楚MapReduce

文章转载自「开发者圆桌」一个关于开发者入门、进阶、踩坑的微信公众号 干巴巴的定义 MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算。概念"Map(映射)"和"Reduce(归约)...

开发者圆桌
2017/03/30
0
0
如何用十分钟学会函数式 Python?

函数式编程到底是什么?本文将详解其概念,同时分享怎样在 Python 中使用函数式编程。主要内容包括列表解析式和其他形式的解析式。 函数式模型 在命令式模型中,执行程序的方式是给计算机一系...

CSDN资讯
09/22
0
0
【编译原理】中间代码(二)

本文是关于中间代码的第二篇文章。在第一篇文章中,我们介绍了3种表示中间代码的方式,本文将接着介绍和静态类型检查以及中间代码生成相关的内容。另外,本文使用第一篇文章中介绍的三地址代...

jzyhywxz
2017/12/13
0
0
Java8 新特性之流式数据处理

一. 流式处理简介 在我接触到java8流式处理的时候,我的第一感觉是流式处理让集合操作变得简洁了许多,通常我们需要多行代码才能完成的操作,借助于流式处理可以在一行中实现。比如我们希望对...

落叶清风
10/10
0
0
用 Kotlin 的函数式编程 替代 GOF 设计模式

用 Kotlin 的函数式编程 替代 GOF 设计模式 函数式编程(FP) 《Kotlin极简教程》正式上架: 点击这里 > 去京东商城购买阅读 点击这里 > 去天猫商城购买阅读 非常感谢您亲爱的读者,大家请多...

程序员诗人
04/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

初级开发-编程题

` public static void main(String[] args) { System.out.println(changeStrToUpperCase("user_name_abc")); System.out.println(changeStrToLowerCase(changeStrToUpperCase("user_name_abc......

小池仔
今天
4
0
现场看路演了!

HiBlock
昨天
8
0
Rabbit MQ基本概念介绍

RabbitMQ介绍 • RabbitMQ是一个消息中间件,是一个很好用的消息队列框架。 • ConnectionFactory、Connection、Channel都是RabbitMQ对外提供的API中最基本的对象。Connection是RabbitMQ的s...

寰宇01
昨天
7
0
官方精简版Windows10:微软自己都看不过去了

微软宣布,该公司正在寻求解决方案,以减轻企业客户的Windows 10规模。该公司声称,企业客户下载整个Windows 10文件以更新设备既费钱又费时。 微软宣布,该公司正在寻求解决方案,以减轻企业...

linux-tao
昨天
9
0
TypeScript基础入门之JSX(二)

转发 TypeScript基础入门之JSX(二) 属性类型检查 键入检查属性的第一步是确定元素属性类型。 内在元素和基于价值的元素之间略有不同。 对于内部元素,它是JSX.IntrinsicElements上的属性类型...

durban
昨天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部