Browse Source

Merge pull request #5701 from cakephp/3.0-fix-extract

Adding the ability of using a callable for Collection::extract()
Mark Story 11 years ago
parent
commit
317e9c5c8e

+ 7 - 7
src/Collection/Iterator/ExtractIterator.php

@@ -24,12 +24,12 @@ class ExtractIterator extends Collection
 {
 
     /**
-     * A path to follow inside a hierarchy in order to get a particular property,
-     * which name is the last in this array
+     * A callable responsible for extracting a single value for each
+     * item in the collection.
      *
-     * @var array
+     * @var callable
      */
-    protected $_path;
+    protected $_extractor;
 
     /**
      * Creates the iterator that will return the requested property for each value
@@ -53,7 +53,7 @@ class ExtractIterator extends Collection
      */
     public function __construct($items, $path)
     {
-        $this->_path = explode('.', $path);
+        $this->_extractor = $this->_propertyExtractor($path);
         parent::__construct($items);
     }
 
@@ -65,7 +65,7 @@ class ExtractIterator extends Collection
      */
     public function current()
     {
-        $current = parent::current();
-        return $this->_extract($current, $this->_path);
+        $extractor = $this->_extractor;
+        return $extractor(parent::current());
     }
 }

+ 17 - 0
tests/TestCase/Collection/Iterator/ExtractIteratorTest.php

@@ -83,4 +83,21 @@ class ExtractIteratorTest extends TestCase
         $extractor = new ExtractIterator($items, 'a.b.c');
         $this->assertEquals([10, null, null, 25], iterator_to_array($extractor));
     }
+
+    /**
+     * Tests that it is possible to pass a callable as the extractor.
+     *
+     * @return void
+     */
+    public function testExtractWithCallable()
+    {
+        $items = [
+            ['a' => 1, 'b' => 2],
+            ['a' => 3, 'b' => 4]
+        ];
+        $extractor = new ExtractIterator($items, function ($item) {
+            return $item['b'];
+        });
+        $this->assertEquals([2, 4], iterator_to_array($extractor));
+    }
 }