ibsciss / php-functional
PHP中的reducer实现
Requires
- php: >=5.3.0
Requires (Dev)
- phpunit/phpunit: 4.*
- scrutinizer/ocular: ~1.1
- squizlabs/php_codesniffer: ~2.3
This package is not auto-updated.
Last update: 2024-09-26 00:14:39 UTC
README
收集一系列函数和类,为您的项目提供一些简洁、一致且经过良好测试的函数式工具。
特别适合轻松构建数据处理算法。
安装
通过Composer
$ composer require ibsciss/php-functionnal
用法
简单示例
想象你想计算10月份的增值税总额
而不是这样做
function compute_october_vat() { $total_vat_amount = 0; foreach ($invoices as $invoice) { if ($invoice->due_date->format('m') == '10') { $total_vat_amount += $invoice->amount * 0.2; } } return $total_vat_amount; }
或者,如果你想尝试使用map / reduce函数
function compute_october_vat() { return array_reduce( array_map( function($invoice) { return $invoice->amount * 0.2; }, array_filter( $invoices, function($invoice) { return $invoice->due_date->format('m') == '10'; } ) ), function($x, $y) { return $x + $y; }, 0); }
你现在可以使用更流畅的API
function compute_october_vat() { return Fp\collection($invoices) ->filter( function($invoice) { return $invoice->due_date->format('m') == '10'; }; ) ->map( function($invoice) { return $invoice->amount * 0.2; }; ) ->add(); }
函数式助手
组合
组合函数允许您从现有函数创建新函数
compose(f,g,h)(x) == f(g(h(x)))
一个实用示例
$plus_one = function($x) { return $x + 1; }; $square = function($x) { return pow($x, 2); }; $plus_one_and_square = Fp\compose($plus_one, $square); $plus_one_and_square(2) //return 9
当然你可以组合尽可能多的函数。
管道函数
管道函数有助于对集合应用转换,Martin Fowler写了一篇非常好的介绍(基于ruby)关于它。在同一博客上,你还可以找到其他资源来学习如何使用管道重构过多的循环。
map
、filter
和reduce
函数是围绕本地PHP函数包装的,要了解我们为什么要这样做,请参阅常见问题解答。
Map
将函数应用于集合中的每个项以创建一个新数组。
//square each item of the collection Fp\map( function($x) { return pow($x, 2); //square function }, [1,2,3] ); //return [1,4,9,16]
Filter
构建一个数组,其中包含在给定的回调中返回true的项。
//return even values from the collection Fp\filter( function($x) { return ($x % 2 == 0); }, [1,2,3,4] ); //return [2,4]
Reduce
通过将每个项传递给给定的回调来累积。回调返回的值用于下一次调用(第一次调用提供一个初始值)。
//sum values of the collection Fp\reduce( function($carry, $item) { return $carray + $item }, [1,2,3,4], 0 ); //return 10
链式调用
您可以通过使用Fp\collection(collection)
函数来链式操作(不要忘记调用values()
以获取结果)
//squared even values from the given collection Fp\collection([1,2,3,4]) ->filter( function($x) { return ($x % 2 == 0); } ) ->map( function($x) { return pow($x, 2); } ) ->values();
集合转换器
使用传统的管道函数,您必须迭代整个集合的每个转换步骤,并创建一个中间集合,这在内存使用上是一个巨大的浪费。
此外,您无法真正提取一个步骤以在其他上下文中使用它,这不利于代码重用。
为了克服传统管道函数的这些缺点,函数式世界带来了一种很好的解决方案:转换器
。
映射
类似于map
过滤
类似filter
标量转换器
与single_result
终端reducer一起使用。
First
返回第一个元素
Max
返回最大值
聚合reducer
批处理
批处理结果
枚举
创建带有结果的索引元组
终端reducer
追加
追加到数组
连接
通过合并实现的不可变追加
single_result
获取标量结果而不是集合
常见问题解答
为什么不直接使用array_*(array_filter、array_map)函数?
- 为了提高API一致性
- 能够在没有省略可迭代对象的情况下产生转换器
- 能够消费
Collection
对象。
变更日志
请参阅变更日志以获取有关最近更改的更多信息。
测试
$ composer test
贡献
请参阅CONTRIBUTING以获取详细信息。
安全
如果您发现任何与安全相关的问题,请通过电子邮件:author_email联系,而不是使用问题跟踪器。
致谢
许可证
MIT许可证(MIT)。请参阅许可证文件以获取更多信息。