Skip to content

Commit

Permalink
Product combinator generator function
Browse files Browse the repository at this point in the history
  • Loading branch information
nicmart authored and nikic committed Jul 2, 2015
1 parent d1340eb commit f444b6f
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ list the function signatures as an overview:
Iterator zip(iterable... $iterables)
Iterator zipKeyValue(iterable $keys, iterable $values)
Iterator chain(iterable... $iterables)
Iterator product(iterable... $iterables)
Iterator slice(iterable $iterable, int $start, int $length = INF)
Iterator take(int $num, iterable $iterable)
Iterator drop(int $num, iterable $iterable)
Expand Down
36 changes: 36 additions & 0 deletions src/iter.php
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,42 @@ function chain(/* ...$iterables */) {
}
}

/**
* Returns the cartesian product of iterables that were passed as arguments.
*
* The resulting iterator will contain all the possible tuples of keys and values.
*
* Please note that the iterables after the first must be rewindable
*
* Examples:
*
* iter\product(iter\range(1, 2), iter\rewindable\range(3, 4))
* => iter([1, 3], [1, 4], [2, 3], [2, 4])
*
* @param mixed[] ...$iterables Iterables to combine
*
* @return \Iterator
*/
function product(/* ...$iterables */) {
$iterables = func_get_args();

if (!$iterables) {
yield [] => [];
return;
}

$head = array_shift($iterables);
$tailProduct = call_user_func_array("iter\\rewindable\\product", $iterables);

foreach ($head as $headKey => $headValue) {
foreach ($tailProduct as $tailKey => $tailValue) {
array_unshift($tailValue, $headValue);
array_unshift($tailKey, $headKey);
yield $tailKey => $tailValue;
}
}
}

/**
* Takes a slice from an iterable.
*
Expand Down
1 change: 1 addition & 0 deletions src/iter.rewindable.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ function reductions() { return new _RewindableGenerator('iter\reductions', fun
function zip() { return new _RewindableGenerator('iter\zip', func_get_args()); }
function zipKeyValue() { return new _RewindableGenerator('iter\zipKeyValue', func_get_args()); }
function chain() { return new _RewindableGenerator('iter\chain', func_get_args()); }
function product() { return new _RewindableGenerator('iter\product', func_get_args()); }
function slice() { return new _RewindableGenerator('iter\slice', func_get_args()); }
function take() { return new _RewindableGenerator('iter\take', func_get_args()); }
function drop() { return new _RewindableGenerator('iter\drop', func_get_args()); }
Expand Down

0 comments on commit f444b6f

Please sign in to comment.