diff --git a/README.md b/README.md index 74aedf6..032ba4d 100644 --- a/README.md +++ b/README.md @@ -8,21 +8,6 @@ Iterable functions Provides additional functions to work with [iterable](https://wiki.php.net/rfc/iterable) variables (even on PHP5.3+). -is_iterable() -------------- -To check wether or not a PHP variable can be looped over in a `foreach` statement, PHP provides an `is_iterable()` function. - -**But this function only works on PHP7.1+**. - -This library ships a polyfill of this function for previous PHP versions. - -Usage: -```php -var_dump(is_iterable(array('foo', 'bar'))); // true -var_dump(is_iterable(new DirectoryIterator(__DIR__))); // true -var_dump(is_iterable('foobar')); // false -``` - iterable_to_array() ------------------- @@ -30,13 +15,15 @@ PHP offers an `iterator_to_array()` function to export any iterator into an arra **But when you want to transform an `iterable` to an array, the `iterable` itself can already be an array.** -When using `iterator_to_array()` with an array, PHP5 triggers a E_RECOVERABLE_ERROR while PHP7 throws a `TypeError`. +When using `iterator_to_array()` with an iterable, that happens to be an array, PHP will throw a `TypeError`. If you need an iterable-agnostic function, try our `iterable_to_array()`: ```php -var_dump(iterable_to_array(new ArrayIterator(array('foo', 'bar')))); // ['foo', 'bar'] -var_dump(iterable_to_array(array('foo', 'bar'))); // ['foo', 'bar'] +use function BenTools\IterableFunctions\iterable_to_array; + +var_dump(iterable_to_array(new \ArrayIterator(['foo', 'bar']))); // ['foo', 'bar'] +var_dump(iterable_to_array(['foo', 'bar'])); // ['foo', 'bar'] ``` iterable_to_traversable() @@ -49,8 +36,10 @@ If your variable is an array, the function converts it to an `ArrayIterator`. Usage: ```php -var_dump(iterable_to_traversable(array('foo', 'bar'))); // ArrayIterator(array('foo', 'bar')) -var_dump(iterable_to_traversable(new ArrayIterator(array('foo', 'bar')))); // ArrayIterator(array('foo', 'bar')) +use function BenTools\IterableFunctions\iterable_to_traversable; + +var_dump(iterable_to_traversable(['foo', 'bar'])); // \ArrayIterator(['foo', 'bar']) +var_dump(iterable_to_traversable(new \ArrayIterator(['foo', 'bar']))); // \ArrayIterator(['foo', 'bar']) ``` @@ -60,6 +49,8 @@ iterable_map() Works like an `array_map` with an `array` or a `Traversable`. ```php +use function BenTools\IterableFunctions\iterable_map; + $generator = function () { yield 'foo'; yield 'bar'; @@ -76,6 +67,8 @@ iterable_reduce() Works like an `reduce` with an `iterable`. ```php +use function BenTools\IterableFunctions\iterable_reduce; + $generator = function () { yield 1; yield 2; @@ -96,6 +89,8 @@ iterable_filter() Works like an `array_filter` with an `array` or a `Traversable`. ```php +use function BenTools\IterableFunctions\iterable_filter; + $generator = function () { yield 0; yield 1; @@ -108,6 +103,8 @@ foreach (iterable_filter($generator()) as $item) { Of course you can define your own filter: ```php +use function BenTools\IterableFunctions\iterable_filter; + $generator = function () { yield 'foo'; yield 'bar'; @@ -123,54 +120,43 @@ foreach (iterable_filter($generator(), $filter) as $item) { } ``` +Iterable fluent interface +========================= -Iterable factory -================ - -When you have an `iterable` type-hint somewhere, and don't know in advance wether you'll pass an `array` or a `Traversable`, just call the magic `iterable()` factory: +The `iterable` function allows you to wrap an iterable and apply some common operations. +With an array input: ```php -interface SomeInterface -{ - /** - * Return an iterable list of items - * - * @return iterable - */ - public function getItems(): iterable; -} - -class MyService implements SomeInterface -{ - /** - * @inheritdoc - */ - public function getItems(): iterable - { - return iterable($this->someOtherService->findAll()): - } +use function BenTools\IterableFunctions\iterable; +$data = [ + 'banana', + 'pineapple', + 'rock', +]; -} +$iterable = iterable($data)->filter(fn($eatable) => 'rock' !== $eatable)->map('strtoupper'); // Traversable of ['banana', 'pineapple'] ``` -It even accepts a `null` value (then converting it to an `EmptyIterator`). - -You may add a `filter` callable and a `map` callable to make your life easier: - +With a traversable input: ```php +use function BenTools\IterableFunctions\iterable; $data = [ 'banana', 'pineapple', - 'potato', + 'rock', ]; -$isFruit = function ($eatable) { - return 'potato' !== $eatable; -}; +$data = fn() => yield from $data; -var_dump(iterator_to_array(iterable($data)->filter($isFruit)->map('strtoupper'))); // ['banana', 'pineapple'] +$iterable = iterable($data())->filter(fn($eatable) => 'rock' !== $eatable)->map('strtoupper'); // Traversable of ['banana', 'pineapple'] ``` +Array output: +```php +$iterable->asArray(); // array ['banana', 'pineapple'] +``` + + Installation ============ @@ -186,6 +172,7 @@ require_once '/path/to/this/library/src/iterable-functions.php'; Unit tests ========== + ``` ./vendor/bin/phpunit ```