Skip to content

Commit d7235b3

Browse files
TWitherscrynobonedriesvints
authored
[10.x] Support sort option flags on sortByMany Collections (#50269)
* [10.x] Support sort option flags on sortByMany Collections * Added docblock * Remove commented code * Styling fix * Update tests/Support/SupportCollectionTest.php Co-authored-by: Mior Muhammad Zaki <[email protected]> * Removed phpunit attribute * Update tests/Support/SupportCollectionTest.php --------- Co-authored-by: Mior Muhammad Zaki <[email protected]> Co-authored-by: Dries Vints <[email protected]>
1 parent d562c06 commit d7235b3

File tree

2 files changed

+103
-6
lines changed

2 files changed

+103
-6
lines changed

src/Illuminate/Collections/Collection.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,7 +1397,7 @@ public function sortDesc($options = SORT_REGULAR)
13971397
public function sortBy($callback, $options = SORT_REGULAR, $descending = false)
13981398
{
13991399
if (is_array($callback) && ! is_callable($callback)) {
1400-
return $this->sortByMany($callback);
1400+
return $this->sortByMany($callback, $options);
14011401
}
14021402

14031403
$results = [];
@@ -1428,13 +1428,14 @@ public function sortBy($callback, $options = SORT_REGULAR, $descending = false)
14281428
* Sort the collection using multiple comparisons.
14291429
*
14301430
* @param array<array-key, (callable(TValue, TValue): mixed)|(callable(TValue, TKey): mixed)|string|array{string, string}> $comparisons
1431+
* @param int $options
14311432
* @return static
14321433
*/
1433-
protected function sortByMany(array $comparisons = [])
1434+
protected function sortByMany(array $comparisons = [], int $options = SORT_REGULAR)
14341435
{
14351436
$items = $this->items;
14361437

1437-
uasort($items, function ($a, $b) use ($comparisons) {
1438+
uasort($items, function ($a, $b) use ($comparisons, $options) {
14381439
foreach ($comparisons as $comparison) {
14391440
$comparison = Arr::wrap($comparison);
14401441

@@ -1452,7 +1453,21 @@ protected function sortByMany(array $comparisons = [])
14521453
$values = array_reverse($values);
14531454
}
14541455

1455-
$result = $values[0] <=> $values[1];
1456+
if (($options & SORT_FLAG_CASE) === SORT_FLAG_CASE) {
1457+
if (($options & SORT_NATURAL) === SORT_NATURAL) {
1458+
$result = strnatcasecmp($values[0], $values[1]);
1459+
} else {
1460+
$result = strcasecmp($values[0], $values[1]);
1461+
}
1462+
} else {
1463+
$result = match ($options) {
1464+
SORT_NUMERIC => intval($values[0]) <=> intval($values[1]),
1465+
SORT_STRING => strcmp($values[0], $values[1]),
1466+
SORT_NATURAL => strnatcmp($values[0], $values[1]),
1467+
SORT_LOCALE_STRING => strcoll($values[0], $values[1]),
1468+
default => $values[0] <=> $values[1],
1469+
};
1470+
}
14561471
}
14571472

14581473
if ($result === 0) {

tests/Support/SupportCollectionTest.php

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2031,9 +2031,9 @@ public function testSortByString($collection)
20312031
$this->assertEquals([['name' => 'dayle'], ['name' => 'taylor']], array_values($data->all()));
20322032

20332033
$data = new $collection([['name' => 'taylor'], ['name' => 'dayle']]);
2034-
$data = $data->sortBy('name', SORT_STRING);
2034+
$data = $data->sortBy('name', SORT_STRING, true);
20352035

2036-
$this->assertEquals([['name' => 'dayle'], ['name' => 'taylor']], array_values($data->all()));
2036+
$this->assertEquals([['name' => 'taylor'], ['name' => 'dayle']], array_values($data->all()));
20372037
}
20382038

20392039
/**
@@ -2077,6 +2077,88 @@ public function testSortByAlwaysReturnsAssoc($collection)
20772077
$this->assertEquals([1 => ['sort' => 1], 0 => ['sort' => 2]], $data->all());
20782078
}
20792079

2080+
#[DataProvider('collectionClassProvider')]
2081+
public function testSortByMany($collection)
2082+
{
2083+
$data = new $collection([['item' => '1'], ['item' => '10'], ['item' => 5], ['item' => 20]]);
2084+
$expected = $data->pluck('item')->toArray();
2085+
2086+
sort($expected);
2087+
$data = $data->sortBy(['item']);
2088+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2089+
2090+
rsort($expected);
2091+
$data = $data->sortBy([['item', 'desc']]);
2092+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2093+
2094+
sort($expected, SORT_STRING);
2095+
$data = $data->sortBy(['item'], SORT_STRING);
2096+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2097+
2098+
rsort($expected, SORT_STRING);
2099+
$data = $data->sortBy([['item', 'desc']], SORT_STRING);
2100+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2101+
2102+
sort($expected, SORT_NUMERIC);
2103+
$data = $data->sortBy(['item'], SORT_NUMERIC);
2104+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2105+
2106+
rsort($expected, SORT_NUMERIC);
2107+
$data = $data->sortBy([['item', 'desc']], SORT_NUMERIC);
2108+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2109+
2110+
$data = new $collection([['item' => 'img1'], ['item' => 'img101'], ['item' => 'img10'], ['item' => 'img11']]);
2111+
$expected = $data->pluck('item')->toArray();
2112+
2113+
sort($expected, SORT_NUMERIC);
2114+
$data = $data->sortBy(['item'], SORT_NUMERIC);
2115+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2116+
2117+
sort($expected);
2118+
$data = $data->sortBy(['item']);
2119+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2120+
2121+
sort($expected, SORT_NATURAL);
2122+
$data = $data->sortBy(['item'], SORT_NATURAL);
2123+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2124+
2125+
$data = new $collection([['item' => 'img1'], ['item' => 'Img101'], ['item' => 'img10'], ['item' => 'Img11']]);
2126+
$expected = $data->pluck('item')->toArray();
2127+
2128+
sort($expected);
2129+
$data = $data->sortBy(['item']);
2130+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2131+
2132+
sort($expected, SORT_NATURAL | SORT_FLAG_CASE);
2133+
$data = $data->sortBy(['item'], SORT_NATURAL | SORT_FLAG_CASE);
2134+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2135+
2136+
sort($expected, SORT_FLAG_CASE | SORT_STRING);
2137+
$data = $data->sortBy(['item'], SORT_FLAG_CASE | SORT_STRING);
2138+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2139+
2140+
sort($expected, SORT_FLAG_CASE | SORT_NUMERIC);
2141+
$data = $data->sortBy(['item'], SORT_FLAG_CASE | SORT_NUMERIC);
2142+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2143+
2144+
$data = new $collection([['item' => 'Österreich'], ['item' => 'Oesterreich'], ['item' => 'Zeta']]);
2145+
$expected = $data->pluck('item')->toArray();
2146+
2147+
sort($expected);
2148+
$data = $data->sortBy(['item']);
2149+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2150+
2151+
sort($expected, SORT_LOCALE_STRING);
2152+
$data = $data->sortBy(['item'], SORT_LOCALE_STRING);
2153+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2154+
2155+
setlocale(LC_ALL, 'de_DE');
2156+
2157+
sort($expected, SORT_LOCALE_STRING);
2158+
$data = $data->sortBy(['item'], SORT_LOCALE_STRING);
2159+
$this->assertEquals($data->pluck('item')->toArray(), $expected);
2160+
}
2161+
20802162
/**
20812163
* @dataProvider collectionClassProvider
20822164
*/

0 commit comments

Comments
 (0)