Browse Source

Merge pull request #7911 from cakephp/collection0chunk

Implemented Collection::chunk()
Mark Story 10 years ago
parent
commit
4d3477285f

+ 16 - 0
src/Collection/CollectionInterface.php

@@ -904,6 +904,22 @@ interface CollectionInterface extends Iterator, JsonSerializable
     public function zipWith($items, $callable);
 
     /**
+     * Breaks the collection into smaller arrays of the given size.
+     *
+     * ### Example:
+     *
+     * ```
+     * $items [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
+     * $chunked = (new Collection($items))->chunk(3)->toList();
+     * // Returns [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11]]
+     * ```
+     *
+     * @param int $chunkSize The maximum size for each chunk
+     * @return \Cake\Collection\CollectionInterface
+     */
+    public function chunk($chunkSize);
+
+    /**
      * Returns whether or not there are elements in this collection
      *
      * ### Example:

+ 20 - 0
src/Collection/CollectionTrait.php

@@ -605,6 +605,26 @@ trait CollectionTrait
      * {@inheritDoc}
      *
      */
+    public function chunk($chunkSize)
+    {
+        return $this->map(function ($v, $k, $iterator) use ($chunkSize) {
+            $values = [$v];
+            for ($i = 1; $i < $chunkSize; $i++) {
+                $iterator->next();
+                if (!$iterator->valid()) {
+                    break;
+                }
+                $values[] = $iterator->current();
+            }
+
+            return $values;
+        });
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     */
     public function isEmpty()
     {
         foreach ($this->unwrap() as $el) {

+ 39 - 0
tests/TestCase/Collection/CollectionTest.php

@@ -1527,4 +1527,43 @@ class CollectionTest extends TestCase
         $unserialized = unserialize($selialized);
         $this->assertEquals($collection->toList(), $unserialized->toList());
     }
+
+    /**
+     * Tests the chunk method with exact chunks
+     *
+     * @return void
+     */
+    public function testChunk()
+    {
+        $collection = new Collection(range(1, 10));
+        $chunked = $collection->chunk(2)->toList();
+        $expected = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]];
+        $this->assertEquals($expected, $chunked);
+    }
+
+    /**
+     * Tests the chunk method with overflowing chunk size
+     *
+     * @return void
+     */
+    public function testChunkOverflow()
+    {
+        $collection = new Collection(range(1, 11));
+        $chunked = $collection->chunk(2)->toList();
+        $expected = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11]];
+        $this->assertEquals($expected, $chunked);
+    }
+
+    /**
+     * Tests the chunk method with non-scalar items
+     *
+     * @return void
+     */
+    public function testChunkNested()
+    {
+        $collection = new Collection([1, 2, 3, [4, 5], 6, [7, [8, 9], 10], 11]);
+        $chunked = $collection->chunk(2)->toList();
+        $expected = [[1, 2], [3, [4, 5]], [6, [7, [8, 9], 10]], [11]];
+        $this->assertEquals($expected, $chunked);
+    }
 }