Skip to content

Commit

Permalink
Add chunkWithKeys()
Browse files Browse the repository at this point in the history
For symmetry with toArray/WithKeys add an explicit
chunkWithKeys() function, which is more obvious than a magic
boolean parameter.
  • Loading branch information
nikic committed May 12, 2019
1 parent f123b81 commit 1417341
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 37 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ list the function signatures as an overview:
Iterator flatten(iterable $iterable, int $levels = INF)
Iterator flip(iterable $iterable)
Iterator chunk(iterable $iterable, int $size, bool $preserveKeys = false)
Iterator chunkWithKeys(iterable $iterable, int $size)
Iterator toIter(iterable $iterable)

Iterator range(number $start, number $end, number $step = null)
Expand Down
22 changes: 20 additions & 2 deletions src/iter.php
Original file line number Diff line number Diff line change
Expand Up @@ -809,11 +809,12 @@ function flip(iterable $iterable): \Iterator {
* Chunks an iterable into arrays of the specified size.
*
* Each chunk is an array (non-lazy), but the chunks are yielded lazily.
* By default keys are not preserved.
*
* Examples:
*
* iter\chunk([1, 2, 3, 4, 5], 3)
* => iter([1, 2, 3], [4, 5])
* iter\chunk([1, 2, 3, 4, 5], 2)
* => iter([1, 2], [3, 4], [5])
*
* @param iterable $iterable The iterable to chunk
* @param int $size The size of each chunk
Expand Down Expand Up @@ -848,6 +849,23 @@ function chunk(iterable $iterable, int $size, bool $preserveKeys = false): \Iter
}
}

/**
* The same as chunk(), but preserving keys.
*
* Examples:
*
* iter\chunkWithKeys(['a' => 1, 'b' => 2, 'c' => 3], 2)
* => iter(['a' => 1, 'b' => 2], ['c' => 3])
*
* @param iterable $iterable The iterable to chunk
* @param int $size The size of each chunk
*
* @return \Iterator An iterator of arrays
*/
function chunkWithKeys(iterable $iterable, int $size): \Iterator {
return chunk($iterable, $size, true);
}

/**
* Joins the elements of an iterable with a separator between them.
*
Expand Down
51 changes: 26 additions & 25 deletions src/iter.rewindable.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,31 +53,32 @@ function callRewindable(callable $function, ...$args) {
* non-rewindable functions from the iter namespace
*/

function range() { return new _RewindableGenerator('iter\range', func_get_args()); }
function map() { return new _RewindableGenerator('iter\map', func_get_args()); }
function mapKeys() { return new _RewindableGenerator('iter\mapKeys', func_get_args()); }
function flatMap() { return new _RewindableGenerator('iter\flatMap', func_get_args()); }
function reindex() { return new _RewindableGenerator('iter\reindex', func_get_args()); }
function filter() { return new _RewindableGenerator('iter\filter', func_get_args()); }
function enumerate() { return new _RewindableGenerator('iter\enumerate', func_get_args()); }
function toPairs() { return new _RewindableGenerator('iter\toPairs', func_get_args()); }
function fromPairs() { return new _RewindableGenerator('iter\fromPairs', func_get_args()); }
function reductions() { return new _RewindableGenerator('iter\reductions', func_get_args()); }
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()); }
function repeat() { return new _RewindableGenerator('iter\repeat', func_get_args()); }
function takeWhile() { return new _RewindableGenerator('iter\takeWhile', func_get_args()); }
function dropWhile() { return new _RewindableGenerator('iter\dropWhile', func_get_args()); }
function keys() { return new _RewindableGenerator('iter\keys', func_get_args()); }
function values() { return new _RewindableGenerator('iter\values', func_get_args()); }
function flatten() { return new _RewindableGenerator('iter\flatten', func_get_args()); }
function flip() { return new _RewindableGenerator('iter\flip', func_get_args()); }
function chunk() { return new _RewindableGenerator('iter\chunk', func_get_args()); }
function range() { return new _RewindableGenerator('iter\range', func_get_args()); }
function map() { return new _RewindableGenerator('iter\map', func_get_args()); }
function mapKeys() { return new _RewindableGenerator('iter\mapKeys', func_get_args()); }
function flatMap() { return new _RewindableGenerator('iter\flatMap', func_get_args()); }
function reindex() { return new _RewindableGenerator('iter\reindex', func_get_args()); }
function filter() { return new _RewindableGenerator('iter\filter', func_get_args()); }
function enumerate() { return new _RewindableGenerator('iter\enumerate', func_get_args()); }
function toPairs() { return new _RewindableGenerator('iter\toPairs', func_get_args()); }
function fromPairs() { return new _RewindableGenerator('iter\fromPairs', func_get_args()); }
function reductions() { return new _RewindableGenerator('iter\reductions', func_get_args()); }
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()); }
function repeat() { return new _RewindableGenerator('iter\repeat', func_get_args()); }
function takeWhile() { return new _RewindableGenerator('iter\takeWhile', func_get_args()); }
function dropWhile() { return new _RewindableGenerator('iter\dropWhile', func_get_args()); }
function keys() { return new _RewindableGenerator('iter\keys', func_get_args()); }
function values() { return new _RewindableGenerator('iter\values', func_get_args()); }
function flatten() { return new _RewindableGenerator('iter\flatten', func_get_args()); }
function flip() { return new _RewindableGenerator('iter\flip', func_get_args()); }
function chunk() { return new _RewindableGenerator('iter\chunk', func_get_args()); }
function chunkWithKeys() { return new _RewindableGenerator('iter\chunkWithKeys', func_get_args()); }

/**
* This class is used for the internal implementation of rewindable
Expand Down
6 changes: 5 additions & 1 deletion test/IterRewindableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,13 @@ public function testRewindableVariants() {
rewindable\flip(['a' => 1, 'b' => 2, 'c' => 3]),
true
);
$this->assertRewindableEquals(
[[1, 2], [3, 4], [5]],
rewindable\chunk([1, 2, 3, 4, 5], 2)
);
$this->assertRewindableEquals(
[['a' => 1, 'b' => 2], ['c' => 3, 'd' => 4], ['e' => 5]],
rewindable\chunk(['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5], 2, true),
rewindable\chunkWithKeys(['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5], 2),
true
);
$this->assertRewindableEquals(
Expand Down
27 changes: 18 additions & 9 deletions test/iterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -439,26 +439,35 @@ public function testChunk() {
['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5]
);

$this->assertSame(
[['a' => 1, 'b' => 2], ['c' => 3, 'd' => 4], ['e' => 5]],
toArray(chunk($iterable, 2, true))
);
$this->assertSame(
[[1, 2], [3, 4], [5]],
toArray(chunk($iterable, 2))
);

$this->assertSame(
[[0=>0, 1=>1], [2=>2, 3=>3]],
toArray(chunk([0, 1, 2, 3], 2, true))
);
$this->assertSame(
[[0, 1], [2, 3]],
toArray(chunk([0, 1, 2, 3], 2))
);

$this->assertSame([[0, 1, 2]], toArray(chunk([0, 1, 2], 100000)));
$this->assertSame([], toArray(chunk([], 100000)));

$this->assertSame(
[['a' => 1, 'b' => 2], ['c' => 3, 'd' => 4], ['e' => 5]],
toArray(chunk($iterable, 2, true))
);
$this->assertSame(
[[0=>0, 1=>1], [2=>2, 3=>3]],
toArray(chunk([0, 1, 2, 3], 2, true))
);

$this->assertSame(
[['a' => 1, 'b' => 2], ['c' => 3, 'd' => 4], ['e' => 5]],
toArray(chunkWithKeys($iterable, 2))
);
$this->assertSame(
[[0=>0, 1=>1], [2=>2, 3=>3]],
toArray(chunkWithKeys([0, 1, 2, 3], 2))
);
}


Expand Down

0 comments on commit 1417341

Please sign in to comment.