在看文件的時候就知道 LazyCollection 搭 Generator 是一個很棒的組合
就誤以為直接丟 generator 就可以當找到 $i > 5 之後就會停止執行迴圈
但事與願違啊
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| use Illuminate\Support\LazyCollection; use PHPUnit\Framework\TestCase;
class ExampleTest extends TestCase { public function test_lazy_collect() { $this->assertEquals(6, LazyCollection::make($this->generator())->collapse()->first(function ($i) { var_dump($i);
return $i > 5; })); }
public function generator() { $x = 1; for ($i = 1; $i <= 9; $i++) { var_dump(sprintf('loop-%02d', $x)); $temp = []; for ($j = 1; $j <= 9; $j++) { $temp[] = $i * $j; } $x++; yield $temp; } } }
|
查了一下原始碼必須用 Closure 來回傳 Generator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| class LazyCollection implements Enumerable { public function __construct($source = null) { if ($source instanceof Closure || $source instanceof self) { $this->source = $source; } elseif (is_null($source)) { $this->source = static::empty(); } else { $this->source = $this->getArrayableItems($source); } }
protected function getArrayableItems($items) { if (is_array($items)) { return $items; } elseif ($items instanceof Enumerable) { return $items->all(); } elseif ($items instanceof Arrayable) { return $items->toArray(); } elseif ($items instanceof Jsonable) { return json_decode($items->toJson(), true); } elseif ($items instanceof JsonSerializable) { return (array) $items->jsonSerialize(); } elseif ($items instanceof Traversable) { return iterator_to_array($items); }
return (array) $items; } }
|
所以正確的寫法應該是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| use Illuminate\Support\LazyCollection; use PHPUnit\Framework\TestCase;
class ExampleTest extends TestCase { public function test_lazy_collect() { $this->assertEquals(6, LazyCollection::make(function () { return $this->generator(); })->collapse()->first(function ($i) { var_dump($i);
return $i > 5; })); }
public function generator() { $x = 1; for ($i = 1; $i <= 9; $i++) { var_dump(sprintf('loop-%02d', $x)); $temp = []; for ($j = 1; $j <= 9; $j++) { $temp[] = $i * $j; } $x++; yield $temp; } } }
string(7) "loop-01" int(1) int(2) int(3) int(4) int(5) int(6)
|
這告訴我們文件必須仔細看啊