Skip to content

Commit 3eb9445

Browse files
authored
Merge pull request #32496 from JosephSilber/take-while
[7.x] Add `takeUntil` and `takeWhile` collection methods
2 parents a4326d8 + 50dabda commit 3eb9445

File tree

5 files changed

+232
-111
lines changed

5 files changed

+232
-111
lines changed

src/Illuminate/Support/Collection.php

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -736,17 +736,6 @@ public function union($items)
736736
return new static($this->items + $this->getArrayableItems($items));
737737
}
738738

739-
/**
740-
* Take items in the collection until the given condition is met.
741-
*
742-
* @param mixed $key
743-
* @return static
744-
*/
745-
public function until($value)
746-
{
747-
return new static($this->lazy()->until($value)->all());
748-
}
749-
750739
/**
751740
* Create a new collection consisting of every n-th element.
752741
*
@@ -1196,6 +1185,28 @@ public function take($limit)
11961185
return $this->slice(0, $limit);
11971186
}
11981187

1188+
/**
1189+
* Take items in the collection until the given condition is met.
1190+
*
1191+
* @param mixed $key
1192+
* @return static
1193+
*/
1194+
public function takeUntil($value)
1195+
{
1196+
return new static($this->lazy()->takeUntil($value)->all());
1197+
}
1198+
1199+
/**
1200+
* Take items in the collection while the given condition is met.
1201+
*
1202+
* @param mixed $key
1203+
* @return static
1204+
*/
1205+
public function takeWhile($value)
1206+
{
1207+
return new static($this->lazy()->takeWhile($value)->all());
1208+
}
1209+
11991210
/**
12001211
* Transform each item in the collection using a callback.
12011212
*

src/Illuminate/Support/LazyCollection.php

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -737,27 +737,6 @@ public function union($items)
737737
return $this->passthru('union', func_get_args());
738738
}
739739

740-
/**
741-
* Take items in the collection until the given condition is met.
742-
*
743-
* @param mixed $key
744-
* @return static
745-
*/
746-
public function until($value)
747-
{
748-
$callback = $this->useAsCallable($value) ? $value : $this->equality($value);
749-
750-
return new static(function () use ($callback) {
751-
foreach ($this as $key => $item) {
752-
if ($callback($item, $key)) {
753-
break;
754-
}
755-
756-
yield $key => $item;
757-
}
758-
});
759-
}
760-
761740
/**
762741
* Create a new collection consisting of every n-th element.
763742
*
@@ -1135,6 +1114,42 @@ public function take($limit)
11351114
});
11361115
}
11371116

1117+
/**
1118+
* Take items in the collection until the given condition is met.
1119+
*
1120+
* @param mixed $key
1121+
* @return static
1122+
*/
1123+
public function takeUntil($value)
1124+
{
1125+
$callback = $this->useAsCallable($value) ? $value : $this->equality($value);
1126+
1127+
return new static(function () use ($callback) {
1128+
foreach ($this as $key => $item) {
1129+
if ($callback($item, $key)) {
1130+
break;
1131+
}
1132+
1133+
yield $key => $item;
1134+
}
1135+
});
1136+
}
1137+
1138+
/**
1139+
* Take items in the collection while the given condition is met.
1140+
*
1141+
* @param mixed $key
1142+
* @return static
1143+
*/
1144+
public function takeWhile($value)
1145+
{
1146+
$callback = $this->useAsCallable($value) ? $value : $this->equality($value);
1147+
1148+
return $this->takeUntil(function ($item, $key) use ($callback) {
1149+
return ! $callback($item, $key);
1150+
});
1151+
}
1152+
11381153
/**
11391154
* Pass each item in the collection to the given callback, lazily.
11401155
*

src/Illuminate/Support/Traits/EnumeratesValues.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ trait EnumeratesValues
6565
'sortBy',
6666
'sortByDesc',
6767
'sum',
68+
'takeUntil',
69+
'takeWhile',
6870
'unique',
6971
'until',
7072
];
@@ -722,6 +724,19 @@ public function uniqueStrict($key = null)
722724
return $this->unique($key, true);
723725
}
724726

727+
/**
728+
* Take items in the collection until the given condition is met.
729+
*
730+
* This is an alias to the "takeUntil" method.
731+
*
732+
* @param mixed $key
733+
* @return static
734+
*/
735+
public function until($value)
736+
{
737+
return $this->takeUntil($value);
738+
}
739+
725740
/**
726741
* Collect the values into a collection.
727742
*

tests/Support/SupportCollectionTest.php

Lines changed: 125 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,6 +1721,131 @@ public function testTakeLast($collection)
17211721
$this->assertEquals([1 => 'dayle', 2 => 'shawn'], $data->all());
17221722
}
17231723

1724+
/**
1725+
* @dataProvider collectionClassProvider
1726+
*/
1727+
public function testTakeUntilUsingValue($collection)
1728+
{
1729+
$data = new $collection([1, 2, 3, 4]);
1730+
1731+
$data = $data->takeUntil(3);
1732+
1733+
$this->assertSame([1, 2], $data->toArray());
1734+
}
1735+
1736+
/**
1737+
* @dataProvider collectionClassProvider
1738+
*/
1739+
public function testTakeUntilUsingCallback($collection)
1740+
{
1741+
$data = new $collection([1, 2, 3, 4]);
1742+
1743+
$data = $data->takeUntil(function ($item) {
1744+
return $item >= 3;
1745+
});
1746+
1747+
$this->assertSame([1, 2], $data->toArray());
1748+
}
1749+
1750+
/**
1751+
* @dataProvider collectionClassProvider
1752+
*/
1753+
public function testTakeUntilReturnsAllItemsForUnmetValue($collection)
1754+
{
1755+
$data = new $collection([1, 2, 3, 4]);
1756+
1757+
$actual = $data->takeUntil(99);
1758+
1759+
$this->assertSame($data->toArray(), $actual->toArray());
1760+
1761+
$actual = $data->takeUntil(function ($item) {
1762+
return $item >= 99;
1763+
});
1764+
1765+
$this->assertSame($data->toArray(), $actual->toArray());
1766+
}
1767+
1768+
/**
1769+
* @dataProvider collectionClassProvider
1770+
*/
1771+
public function testTakeUntilCanBeProxied($collection)
1772+
{
1773+
$data = new $collection([
1774+
new TestSupportCollectionHigherOrderItem('Adam'),
1775+
new TestSupportCollectionHigherOrderItem('Taylor'),
1776+
new TestSupportCollectionHigherOrderItem('Jason'),
1777+
]);
1778+
1779+
$actual = $data->takeUntil->is('Jason');
1780+
1781+
$this->assertCount(2, $actual);
1782+
$this->assertSame('Adam', $actual->get(0)->name);
1783+
$this->assertSame('Taylor', $actual->get(1)->name);
1784+
}
1785+
1786+
/**
1787+
* @dataProvider collectionClassProvider
1788+
*/
1789+
public function testTakeWhileUsingValue($collection)
1790+
{
1791+
$data = new $collection([1, 1, 2, 2, 3, 3]);
1792+
1793+
$data = $data->takeWhile(1);
1794+
1795+
$this->assertSame([1, 1], $data->toArray());
1796+
}
1797+
1798+
/**
1799+
* @dataProvider collectionClassProvider
1800+
*/
1801+
public function testTakeWhileUsingCallback($collection)
1802+
{
1803+
$data = new $collection([1, 2, 3, 4]);
1804+
1805+
$data = $data->takeWhile(function ($item) {
1806+
return $item < 3;
1807+
});
1808+
1809+
$this->assertSame([1, 2], $data->toArray());
1810+
}
1811+
1812+
/**
1813+
* @dataProvider collectionClassProvider
1814+
*/
1815+
public function testTakeWhileReturnsNoItemsForUnmetValue($collection)
1816+
{
1817+
$data = new $collection([1, 2, 3, 4]);
1818+
1819+
$actual = $data->takeWhile(2);
1820+
1821+
$this->assertSame([], $actual->toArray());
1822+
1823+
$actual = $data->takeWhile(function ($item) {
1824+
return $item == 99;
1825+
});
1826+
1827+
$this->assertSame([], $actual->toArray());
1828+
}
1829+
1830+
/**
1831+
* @dataProvider collectionClassProvider
1832+
*/
1833+
public function testTakeWhileCanBeProxied($collection)
1834+
{
1835+
$data = new $collection([
1836+
new TestSupportCollectionHigherOrderItem('Adam'),
1837+
new TestSupportCollectionHigherOrderItem('Adam'),
1838+
new TestSupportCollectionHigherOrderItem('Taylor'),
1839+
new TestSupportCollectionHigherOrderItem('Taylor'),
1840+
]);
1841+
1842+
$actual = $data->takeWhile->is('Adam');
1843+
1844+
$this->assertCount(2, $actual);
1845+
$this->assertSame('Adam', $actual->get(0)->name);
1846+
$this->assertSame('Adam', $actual->get(1)->name);
1847+
}
1848+
17241849
/**
17251850
* @dataProvider collectionClassProvider
17261851
*/
@@ -4094,68 +4219,6 @@ public function testCollect($collection)
40944219
], $data->all());
40954220
}
40964221

4097-
/**
4098-
* @dataProvider collectionClassProvider
4099-
*/
4100-
public function testUntilUsingValue($collection)
4101-
{
4102-
$data = new $collection([1, 2, 3, 4]);
4103-
4104-
$data = $data->until(3);
4105-
4106-
$this->assertSame([1, 2], $data->toArray());
4107-
}
4108-
4109-
/**
4110-
* @dataProvider collectionClassProvider
4111-
*/
4112-
public function testUntilUsingCallback($collection)
4113-
{
4114-
$data = new $collection([1, 2, 3, 4]);
4115-
4116-
$data = $data->until(function ($item) {
4117-
return $item >= 3;
4118-
});
4119-
4120-
$this->assertSame([1, 2], $data->toArray());
4121-
}
4122-
4123-
/**
4124-
* @dataProvider collectionClassProvider
4125-
*/
4126-
public function testUntilReturnsAllItemsForUnmetValue($collection)
4127-
{
4128-
$data = new $collection([1, 2, 3, 4]);
4129-
4130-
$actual = $data->until(99);
4131-
4132-
$this->assertSame($data->toArray(), $actual->toArray());
4133-
4134-
$actual = $data->until(function ($item) {
4135-
return $item >= 99;
4136-
});
4137-
4138-
$this->assertSame($data->toArray(), $actual->toArray());
4139-
}
4140-
4141-
/**
4142-
* @dataProvider collectionClassProvider
4143-
*/
4144-
public function testUntilCanBeProxied($collection)
4145-
{
4146-
$data = new $collection([
4147-
new TestSupportCollectionHigherOrderItem('Adam'),
4148-
new TestSupportCollectionHigherOrderItem('Taylor'),
4149-
new TestSupportCollectionHigherOrderItem('Jason'),
4150-
]);
4151-
4152-
$actual = $data->until->is('Jason');
4153-
4154-
$this->assertCount(2, $actual);
4155-
$this->assertSame('Adam', $actual->get(0)->name);
4156-
$this->assertSame('Taylor', $actual->get(1)->name);
4157-
}
4158-
41594222
/**
41604223
* Provides each collection class, respectively.
41614224
*

0 commit comments

Comments
 (0)