jumpifbelow/php-functional-array
Composer 安装命令:
composer require jumpifbelow/php-functional-array
包简介
Classes to make the use of sets functional
README 文档
README
Development stage
The project is in a fairly advanced development phase. The API should be stable from now, but it is still possible that huge changes would be made. As small as it could be, any breaking change will come in major release, whatever it is.
General note
This package comes with 3 interfaces and 3 classes implementing them. Purpose of each interfaces:
FluentArrayInterface: allowing to use native PHP function in an object-oriented way.ExtendedArrayInterface: likeFluentArrayInterfacebut with custom operations implemented. It should be the one you want to use if you seek for more functionalities. If you do prefer to ensure the native performance of PHP, avoiding that class would ensure you that the called methods are using native PHP functions.FluentIteratorInterface: inspired byFluentArrayInterface, but for virtually infinite set. It has less functions as many would not make sense to provide, but it handles big set without exhausting memory. It will only execute altering methods once iterating through it, allowing to handle exactly where your code will be executed, rather than on-call. It would handle a lot better any stream or resource providing data.
How to install it?
Just run Composer:
composer require jumpifbelow/php-functional-array
How to use it?
FluentArray
Two types of array are made.
The first, JumpIfBelow\Arrays\FluentArrayInterface is
made to work like a PHP array, with all functions builtin directly in methods.
All of the calls are immutable and fluent, meaning you can chain it without
altering the first reference. The only exceptions is when managing internal pointer,
where it won't send a new object as it would break the iterator.
The second, JumpIfBelow\Arrays\ExtendedArrayInterface is made to be like JumpIfBelow\Arrays\FluentArrayInterface.
However, as it lacks some common methods, it adds them to be easier to handle.
Of course, the package comes with implementations you can already use like this:
<?php
use JumpIfBelow\Arrays\FluentArray;
$a = FluentArray::from([
5,
'er',
'ert',
'loop',
false,
null,
]);
$newArray = $a
->filter(function ($x): bool {
return is_string($x);
})
->map(function (string $x): string {
return strrev($x);
})
->sort()
;
var_dump($newArray->toArray());
// those examples could be shortened because they are using defined functions
// note that the interface accepts any callable, which allow this writing
$newArray = $a
->filter('is_string')
->map('strrev')
->sort()
;
// you can quickly setup an array and directly operate with it too
$pairSquareSum = FluentArray
::from([1, 4, 6, 5, 9, 8, 0])
->filter(fn(int $x) => $x % 2 === 0)
->map(fn(int $x) => $x ** 2)
->reduce(fn(int $sum, int $x) => $sum + $x, 0)
;
FluentIterable
Then, there is the iterable object FluentIterable.
It is made with the idea to handle infinite sets without exhausting all of the memory and ending up with an error. Therefore, the execution relies a lot more on the CPU, the rest depending on your code. As it will be executed on run-time, the items will go through operators one by one, instead of generating getting each step completed before going to another one. This is benefical as you will receive items one by one as they are processed, rather than the whole big result block. You could imagine reading and parsing a very large file, while only acting on certain line, without having to load the whole file in the memory, but only the parts you are interested in.
<?php
use JumpIfBelow\Arrays\FluentIterable;
// we are creating a sum of a column in a CSV file
$sum = FluentIterable
::from(function () {
$f = fopen('myfile.csv', 'r');
while (($line = fgetcsv($f)) !== false) {
yield $line;
}
fclose($f);
})
->map(fn (array $row) => $row[1])
->filter(fn (int $value) => $value >= 0)
->reduce(fn (int $sum, int $value) => $sum + $value, 0)
;
// all of the code, from file opening and operations will only be executed when reduce is started
// once reduce is done, it will close the file handler
Note that transforming a FluentIterable to another one is an operation handled by an OperatorInterface.
So while using the map operation, you only call in fact the MapOperator internally.
The APIs are public to allow using your very own operators if needed.
If we retake the above example, we could write it this way:
<?php
use JumpIfBelow\Arrays\FluentIterable;
use JumpIfBelow\Arrays\IterableOperator\{
FilterOperator,
MapOperator,
};
$sum = FluentIterable
::from(function () {
$f = fopen('myfile.csv', 'r');
while (($line = fgetcsv($f)) !== false) {
yield $line;
}
fclose($f);
})
->apply(
MapOperator::with(fn (array $row) => $row[1]),
FilterOperator::with(fn (int $value) => $value >= 0),
)
->reduce(fn (int $sum, int $value) => $sum + $value, 0)
;
It is also powerful enough not to generate everything at once.
For example, this would exhaust the memory right from the range call:
<?php
use JumpIfBelow\Arrays\FluentArray;
$array = FluentArray
::range(1, 2 ** 32 - 1)
->filter(fn (int $v): bool => $v >= 10 ** 7 && $v < 10 ** 8)
->slice(5, 10)
;
Meanwhile, you can go with a far greater set, filtering it, getting only a part of it, without actually going in the whole set. In this example, we would go from 0 to 2 ** 64 (if you are on a 64-bits OS). Then, only filtering values between 10,000,000 and 100,000,000. Afterwards, getting the values starting after the 5th one, and keeping only 10 of them. The whole set will not be generated all at once, and will not go further than 10,000,014.
<?php
use JumpIfBelow\Arrays\FluentIterable;
$iterable = FluentIterable
::range(0, PHP_INT_MAX)
->filter(fn (int $v): bool => $v >= 10 ** 7 && $v < 10 ** 8)
->slice(5, 10)
;
Immutable and mutable methods
This is supposed to only use immutable reference, meaning calling any function that edit the content should return a new version of the array with the altered data. The old reference remains unmodified. There are exceptions to this behavior because of the way some functions are behaving. Here is a list of methods:
FluentArray
Mutable
popshift
Immutable
arsortasortchangeKeyCasechunkcolumncombinecountValuesdiffdiffAssocdiffKeydiffUassocdiffUkeyfillKeysfilterflipintersectintersectAssocintersectKeyintersectUassocintersectUkeykeyskrsortksortmapmergemergeRecursivemultisortnatcasesortnatsortpadpushrandreplacereplaceRecursivereversersortshuffleslicesortspliceuasortudiffudiffAssocudiffUassocuintersectuintersectAssocuintersectUassocuksortuniqueunshiftusortvalueswalkwalkRecursive
ExtendedArray
Mutable
nextKeynextValuenextEntry
Immutable
forEacheverysomeentryfindKeyfindValuequantilesquantileKeysquantileValuesflatgroupByindexByfetchswapwithfullMapfullReducepermutationfirstlast
FluentIterable
Mutable
None
Immutable
applyforEachmapfilterreducereplacesliceuniqueindexBysomeeverytoArray
jumpifbelow/php-functional-array 适用场景与选型建议
jumpifbelow/php-functional-array 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 6.36k 次下载、GitHub Stars 达 1, 最近一次更新时间为 2019 年 02 月 07 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「generator」 「fluent」 「array」 「functional」 「immutable」 「iterable」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 jumpifbelow/php-functional-array 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 jumpifbelow/php-functional-array 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 jumpifbelow/php-functional-array 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Memio's PrettyPrinter, used to generate PHP code from given Model
A set of useful PHP classes.
Presentation and Formatting helper with nice fluent interface.
Trait providing methods to set class properties with an array.
Traits gathering fluent syntax common methods
Traits to build collections of specific objects
统计信息
- 总下载量: 6.36k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 21
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: GPL-3.0-only
- 更新时间: 2019-02-07