diff --git a/src/Illuminate/Support/Traits/EnumeratesValues.php b/src/Illuminate/Support/Traits/EnumeratesValues.php index 83cef4b41dd6..7d143a48fe80 100644 --- a/src/Illuminate/Support/Traits/EnumeratesValues.php +++ b/src/Illuminate/Support/Traits/EnumeratesValues.php @@ -36,6 +36,7 @@ * @property-read HigherOrderCollectionProxy $sortByDesc * @property-read HigherOrderCollectionProxy $sum * @property-read HigherOrderCollectionProxy $unique + * @property-read HigherOrderCollectionProxy $until */ trait EnumeratesValues { @@ -47,7 +48,7 @@ trait EnumeratesValues protected static $proxies = [ 'average', 'avg', 'contains', 'each', 'every', 'filter', 'first', 'flatMap', 'groupBy', 'keyBy', 'map', 'max', 'min', 'partition', - 'reject', 'some', 'sortBy', 'sortByDesc', 'sum', 'unique', + 'reject', 'some', 'sortBy', 'sortByDesc', 'sum', 'unique', 'until', ]; /** @@ -703,6 +704,32 @@ public function uniqueStrict($key = null) return $this->unique($key, true); } + /** + * Take items in the collection until condition is met. + * + * @param mixed $key + * @return static + */ + public function until($value) + { + $passed = []; + + $callback = $this->useAsCallable($value) ? $value : + function ($item) use ($value) { + return $item === $value; + }; + + foreach ($this as $key => $item) { + if ($callback($item, $key)) { + break; + } + + $passed[$key] = $item; + } + + return new static($passed); + } + /** * Collect the values into a collection. * diff --git a/tests/Support/SupportCollectionTest.php b/tests/Support/SupportCollectionTest.php index 5aaa0a921ed5..88f72af89fd7 100755 --- a/tests/Support/SupportCollectionTest.php +++ b/tests/Support/SupportCollectionTest.php @@ -4070,6 +4070,68 @@ public function testCollect($collection) ], $data->all()); } + /** + * @dataProvider collectionClassProvider + */ + public function testUntilUsingValue($collection) + { + $data = new $collection([1, 2, 3, 4]); + + $data = $data->until(3); + + $this->assertSame([1, 2], $data->toArray()); + } + + /** + * @dataProvider collectionClassProvider + */ + public function testUntilUsingCallback($collection) + { + $data = new $collection([1, 2, 3, 4]); + + $data = $data->until(function ($item) { + return $item >= 3; + }); + + $this->assertSame([1, 2], $data->toArray()); + } + + /** + * @dataProvider collectionClassProvider + */ + public function testUntilReturnsAllItemsForUnmetValue($collection) + { + $data = new $collection([1, 2, 3, 4]); + + $actual = $data->until(99); + + $this->assertSame($data->toArray(), $actual->toArray()); + + $actual = $data->until(function ($item) { + return $item >= 99; + }); + + $this->assertSame($data->toArray(), $actual->toArray()); + } + + /** + * @dataProvider collectionClassProvider + */ + public function testUntilCanBeProxied($collection) + { + $data = new $collection([ + new TestSupportCollectionHigherOrderItem('Adam'), + new TestSupportCollectionHigherOrderItem('Taylor'), + new TestSupportCollectionHigherOrderItem('Jason'), + ]); + + $actual = $data->until->is('Jason'); + + $this->assertCount(2, $actual); + $this->assertSame('Adam', $actual->get(0)->name); + $this->assertSame('Taylor', $actual->get(1)->name); + } + /** * Provides each collection class, respectively. * @@ -4097,6 +4159,11 @@ public function uppercase() { return $this->name = strtoupper($this->name); } + + public function is($name) + { + return $this->name === $name; + } } class TestAccessorEloquentTestStub