Skip to content

Commit e9ce376

Browse files
[12.x] Add Arr::sole() method (#55070)
* Add Arr::sole() * Update Collection.php * Style * Update Arr.php --------- Co-authored-by: Taylor Otwell <[email protected]>
1 parent 34f4932 commit e9ce376

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

src/Illuminate/Collections/Arr.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,34 @@ public static function shuffle($array)
807807
return (new Randomizer)->shuffleArray($array);
808808
}
809809

810+
/**
811+
* Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception.
812+
*
813+
* @param array $array
814+
* @param callable $callback
815+
*
816+
* @throws \Illuminate\Support\ItemNotFoundException
817+
* @throws \Illuminate\Support\MultipleItemsFoundException
818+
*/
819+
public static function sole($array, ?callable $callback = null)
820+
{
821+
if ($callback) {
822+
$array = static::where($array, $callback);
823+
}
824+
825+
$count = count($array);
826+
827+
if ($count === 0) {
828+
throw new ItemNotFoundException;
829+
}
830+
831+
if ($count > 1) {
832+
throw new MultipleItemsFoundException($count);
833+
}
834+
835+
return static::first($array);
836+
}
837+
810838
/**
811839
* Sort the array using the given callback or "dot" notation.
812840
*

tests/Support/SupportArrTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
use Illuminate\Support\Arr;
77
use Illuminate\Support\Carbon;
88
use Illuminate\Support\Collection;
9+
use Illuminate\Support\ItemNotFoundException;
10+
use Illuminate\Support\MultipleItemsFoundException;
911
use InvalidArgumentException;
1012
use PHPUnit\Framework\TestCase;
1113
use stdClass;
@@ -1067,6 +1069,35 @@ public function testShuffleKeepsSameValues()
10671069
$this->assertEquals($input, $shuffled);
10681070
}
10691071

1072+
public function testSoleReturnsFirstItemInCollectionIfOnlyOneExists()
1073+
{
1074+
$this->assertSame('foo', Arr::sole(['foo']));
1075+
1076+
$array = [
1077+
['name' => 'foo'],
1078+
['name' => 'bar'],
1079+
];
1080+
1081+
$this->assertSame(
1082+
['name' => 'foo'],
1083+
Arr::sole($array, fn (array $value) => $value['name'] === 'foo')
1084+
);
1085+
}
1086+
1087+
public function testSoleThrowsExceptionIfNoItemsExist()
1088+
{
1089+
$this->expectException(ItemNotFoundException::class);
1090+
1091+
Arr::sole(['foo'], fn (string $value) => $value === 'baz');
1092+
}
1093+
1094+
public function testSoleThrowsExceptionIfMoreThanOneItemExists()
1095+
{
1096+
$this->expectExceptionObject(new MultipleItemsFoundException(2));
1097+
1098+
Arr::sole(['baz', 'foo', 'baz'], fn (string $value) => $value === 'baz');
1099+
}
1100+
10701101
public function testEmptyShuffle()
10711102
{
10721103
$this->assertEquals([], Arr::shuffle([]));

0 commit comments

Comments
 (0)