Skip to content

Commit

Permalink
Add iter\recurse()
Browse files Browse the repository at this point in the history
  • Loading branch information
nikic committed Sep 27, 2016
1 parent 82409a6 commit e601979
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ list the function signatures as an overview:
void apply(callable $function, iterable $iterable)
string join(string $separator, iterable $iterable)
int count(iterable $iterable)
mixed recurse(callable $function, $iterable)
array toArray(iterable $iterable)
array toArrayWithKeys(iterable $iterable)
bool isIterable($value)
Expand Down
24 changes: 24 additions & 0 deletions src/iter.php
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,30 @@ function count($iterable) {
return $count;
}

/**
* Recursively applies a function, working on entire iterables rather than
* individual values.
*
* The function will be called both on the passed iterable and all iterables it
* contains, etc. The call sequence is in post-order (inner before outer).
*
* Examples:
*
* iter\recurse('iter\toArray',
* new ArrayIterator([1, 2, new ArrayIterator([3, 4])]));
* => [1, 2, [3, 4]]
*
* @param callable $function
* @param $iterable
* @return mixed
*/
function recurse(callable $function, $iterable) {
_assertIterable($iterable, 'Second argument');
return $function(map(function($value) use($function) {
return isIterable($value) ? recurse($function, $value) : $value;
}, $iterable));
}

/**
* Converts any iterable into an Iterator.
*
Expand Down
15 changes: 15 additions & 0 deletions test/iterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,21 @@ function() {
);
}

function testRecurse() {
$iter = new \ArrayIterator(['a' => 1, 'b' => 2,
'c' => new \ArrayIterator(['d' => 3, 'e' => 4])]);

$this->assertSame(
[1, 2, [3, 4]],
recurse('iter\toArray', $iter)
);

$this->assertSame(
['a' => 1, 'b' => 2, 'c' => ['d' => 3, 'e' => 4]],
recurse('iter\toArrayWithKeys', $iter)
);
}

private function assertKeysValues(array $keys, array $values, callable $fn) {
$this->assertSame($keys, toArray(keys($fn())));
$this->assertSame($values, toArray(values($fn())));
Expand Down

0 comments on commit e601979

Please sign in to comment.