Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/Ibsciss/php-functional
functional tools implementation in PHP
https://github.com/Ibsciss/php-functional
Last synced: about 2 months ago
JSON representation
functional tools implementation in PHP
- Host: GitHub
- URL: https://github.com/Ibsciss/php-functional
- Owner: Ibsciss
- License: mit
- Created: 2015-06-26T11:39:48.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2016-03-17T21:43:05.000Z (almost 9 years ago)
- Last Synced: 2024-04-07T12:02:53.554Z (10 months ago)
- Language: PHP
- Homepage: https://github.com/Ibsciss/php-functional
- Size: 43.9 KB
- Stars: 13
- Watchers: 6
- Forks: 2
- Open Issues: 13
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.md
Awesome Lists containing this project
README
# Php Functional
[![Join the chat at https://gitter.im/Ibsciss/php-functional](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Ibsciss/php-functional?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)
[![Travis CI](https://travis-ci.org/Ibsciss/php-functional.svg?branch=master)](https://travis-ci.org/Ibsciss/php-functional)
[![Code Coverage](https://scrutinizer-ci.com/g/Ibsciss/php-functional/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/Ibsciss/php-functional/?branch=master)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/Ibsciss/php-functional/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/Ibsciss/php-functional/?branch=master)
[![Build Status](https://scrutinizer-ci.com/g/Ibsciss/php-functional/badges/build.png?b=master)](https://scrutinizer-ci.com/g/Ibsciss/php-functional/build-status/master)A collection of functions and classes to provide some nice functional tools for your projects, with a simple, **consistent** and well tested api.
Especially useful to build data processing algorithms in a breeze.
## Install
Via Composer
``` bash
$ composer require ibsciss/php-functionnal
```## Usage
### Simple example
Imagine you want to compute the total VAT amount for october:
Instead of doing things like this:
```php
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;
}
```Or, if you want to try with map / reduce functions:
```php
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);
}
```You can now use a more fluent api:
```php
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();
}
```## Functional helper
### Compose
The compose function give you the ability to create a new functions from existing functions:
```
compose(f,g,h)(x) == f(g(h(x)))
```A practical example:
```php
$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
```_Of course you can compose as much functions as you want._
### Pipelines functions
Pipelines functions are useful to apply transformations to collections, Martin Fowler wrote a [very good introduction (based on ruby)](http://martinfowler.com/articles/collection-pipeline/) about it.
On the same blog, you'll find another resource to learn [how to refactor your too many loops using pipeline](http://martinfowler.com/articles/refactoring-pipelines.html).The `map`, `filter` and `reduce` functions are wrapper around the native php function, to understand why we have made them please see the [FAQ](#faq).
#### Map
Apply a function to each item of a collection to create a new array.
```php
//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
Build an array composed with items that returns true when passed in the given callback.
```php
//return even values from the collection
Fp\filter(
function($x) {
return ($x % 2 == 0);
},
[1,2,3,4]
); //return [2,4]
```#### Reduce
It makes an accumulation by passing each item to the given callback.
The callback returning value is returned for the next call (an init value is provided for the first call).```php
//sum values of the collection
Fp\reduce(
function($carry, $item) {
return $carray + $item
},
[1,2,3,4],
0
); //return 10
```#### Chaining
You can chain operations by using the `Fp\collection(collection)` function (don't forget to call `values()` to get the results):
```php
//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();
```### Collection transducers
With classical pipeline functions, you have to iterate the whole collection for each step of the transformation
and create an intermediate collection which is a massive waste in memory usage.Moreover you can't really extract a step to use it in other contexts which is bad for code reuse.
To tackle these downsides of classic pipeline function, the functional world come with a nice solution: `tranducers`.
#### Mapping
like map#### Filtering
like filter### scalar transducer
Use with `single_result` terminal reducer.
#### First
return the first element#### Max
return the max### Aggregate reducer
#### Batching
Batch result#### Enumerating
Create indexed tuples with results### Terminal reducer
#### appending
append to an array#### conjoining
immutable appending by merge#### single_result
to get a scalar result instead of a collection## FAQ
### Why not using directly array_\* (array_filter, array_map) functions ?
- To improve api consistency
- To be able to produce transducers if the iterable is omitted
- To be able to consume `Collection` objects.## Change log
Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.
## Testing
``` bash
$ composer test
```## Contributing
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
## Security
If you discover any security related issues, please email :author_email instead of using the issue tracker.
## Credits
- [Arnaud LEMAIRE](https://github.com/lilobase)
- [All Contributors](../../contributors)## License
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.