Skip to content

Commit

Permalink
New function iterable_to_traversable()
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-synapse committed May 3, 2017
1 parent a48bd24 commit b5f1cf5
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 4 deletions.
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ Iterable functions

Provides additional functions to work with [iterable](https://wiki.php.net/rfc/iterable) variables (even on PHP5.3+).

is_iterable
-----------
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+**.
Expand All @@ -25,8 +25,8 @@ var_dump(is_iterable(new DirectoryIterator(__DIR__))); // true
var_dump(is_iterable('foobar')); // false
```

iterable_to_array
-----------------
iterable_to_array()
-------------------

PHP offers an `iterator_to_array()` function to export any iterator into an array.

Expand All @@ -41,6 +41,20 @@ var_dump(iterable_to_array(new ArrayIterator(array('foo', 'bar')))); // ['foo',
var_dump(iterable_to_array(array('foo', 'bar'))); // ['foo', 'bar']
```

iterable_to_traversable()
-------------------------
Useful when you have a `Traversable` type-hint, and you don't know wether or not your argument will be an array or an iterator.

If your variable is already an instance of `Traversable` (i.e. an `Iterator`, an `IteratorAggregate` or a `Generator`), the function simply returns it directly.

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'))
```

Installation
============

Expand Down
1 change: 1 addition & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<testsuite name="Test Suite">
<file>tests/TestIsIterable.php</file>
<file>tests/TestIterableToArray.php</file>
<file>tests/TestIterableToTraversable.php</file>
</testsuite>
</testsuites>
<filter>
Expand Down
15 changes: 15 additions & 0 deletions src/iterable-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,18 @@ function iterable_to_array($iterable)
return is_array($iterable) ? $iterable : iterator_to_array($iterable);
}
}

if (!function_exists('iterable_to_traversable')) {
function iterable_to_traversable($iterable)
{
if ($iterable instanceof Traversable) {
return $iterable;
}
elseif (is_array($iterable)) {
return new ArrayIterator($iterable);
}
else {
throw new \InvalidArgumentException(sprintf('Expected array or \\Traversable, got %s', is_object($iterable) ? get_class($iterable) : gettype($iterable)));
}
}
}
38 changes: 38 additions & 0 deletions tests/TestIterableToTraversable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

use PHPUnit\Framework\TestCase;

class TestIterableToTraversable extends TestCase
{

public function testFunctionExists()
{
$this->assertTrue(function_exists('iterable_to_traversable'));
}

public function testIteratorToTraversable()
{
$iterator = new ArrayIterator(array('foo' => 'bar'));
$traversable = iterable_to_traversable($iterator);
$this->assertSame($iterator, $traversable);
$this->assertInstanceOf('Traversable', $iterator);
}

public function testArrayToTraversable()
{
$array = array('foo' => 'bar');
$traversable = iterable_to_traversable($array);
$this->assertEquals(new ArrayIterator(array('foo' => 'bar')), $traversable);
$this->assertInstanceOf('Traversable', $traversable);
}

/**
* @expectedException InvalidArgumentException
*/
public function testInvalidArgument()
{
$string = 'foo';
iterable_to_traversable($string);
var_dump(iterable_to_traversable(array('foo', 'bar')));
}
}

0 comments on commit b5f1cf5

Please sign in to comment.