-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
180 additions
and
2 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace Zrnik\MkSQL\Utilities\Sorting; | ||
|
||
class SortedObject | ||
{ | ||
/** | ||
* @param int|string $key | ||
* @param object $object | ||
*/ | ||
public function __construct(public mixed $key, public object $object) | ||
{ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace Zrnik\MkSQL\Utilities\Sorting; | ||
|
||
use function array_key_exists; | ||
use function chr; | ||
use function count; | ||
use function ord; | ||
|
||
class Sorting | ||
{ | ||
|
||
|
||
/** | ||
* WILL NOT PRESERVE KEY! | ||
* @param object[] $objects | ||
* @param string $propertyName | ||
* @param bool $preserveKeys | ||
* @return object[] | ||
*/ | ||
public static function sortObjectsByProperty(array $objects, string $propertyName, bool $preserveKeys = false): array | ||
{ | ||
|
||
/** @var array<string, SortedObject> $arrayToSort */ | ||
$arrayToSort = []; | ||
|
||
|
||
foreach ($objects as $key => $object) { | ||
|
||
$sortableKey = (string)$object->$propertyName; | ||
|
||
while (array_key_exists($sortableKey, $arrayToSort)) { | ||
$sortableKey = self::incrementKey($sortableKey); | ||
} | ||
|
||
$arrayToSort[$sortableKey] = new SortedObject($key, $object); | ||
} | ||
|
||
ksort($arrayToSort); | ||
|
||
$result = []; | ||
foreach ($arrayToSort as $sortedObject) { | ||
if ($preserveKeys) { | ||
$result[$sortedObject->key] = $sortedObject->object; | ||
} else { | ||
$result[] = $sortedObject->object; | ||
} | ||
} | ||
|
||
return $result; | ||
|
||
} | ||
|
||
private static function incrementKey(string $sortableKey): string | ||
{ | ||
$chars = str_split($sortableKey); | ||
$lastIndex = count($chars) - 1; | ||
$chars[$lastIndex] = chr(ord($chars[$lastIndex]) + 1); | ||
return implode('', $chars); | ||
} | ||
|
||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace Tests\Utilities\Sorting; | ||
|
||
use Brick\DateTime\LocalDate; | ||
|
||
class SortableClass | ||
{ | ||
public function __construct( | ||
public string $name, | ||
public string $text, | ||
public LocalDate $date, | ||
) | ||
{ } | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace Tests\Utilities\Sorting; | ||
|
||
use Brick\DateTime\LocalDate; | ||
use PHPUnit\Framework\TestCase; | ||
use Zrnik\MkSQL\Utilities\Sorting\Sorting; | ||
|
||
class SortingTest extends TestCase | ||
{ | ||
public function testSorting(): void | ||
{ | ||
$sortable1 = new SortableClass( | ||
'First', 'y', LocalDate::of(2002,1,1) | ||
); | ||
|
||
$sortable2 = new SortableClass( | ||
'Second', 'z', LocalDate::of(2002,1,1) | ||
); | ||
|
||
$sortable3 = new SortableClass( | ||
'Third', 'z', LocalDate::of(2001,1,2) | ||
); | ||
|
||
$sortable4 = new SortableClass( | ||
'Third', 'z', LocalDate::of(2000,1,2) | ||
); | ||
|
||
$sorted = Sorting::sortObjectsByProperty( | ||
[$sortable3, $sortable2, $sortable1], 'name' | ||
); | ||
|
||
static::assertSame([$sortable1, $sortable2, $sortable3], $sorted); | ||
|
||
$sorted = Sorting::sortObjectsByProperty( | ||
[$sortable2, $sortable1, $sortable3], 'text' | ||
); | ||
|
||
static::assertSame([$sortable1, $sortable2, $sortable3], $sorted); | ||
|
||
$sorted = Sorting::sortObjectsByProperty( | ||
[$sortable3, $sortable1, $sortable2, $sortable4], 'text' | ||
); | ||
|
||
static::assertSame([$sortable1, $sortable3, $sortable2, $sortable4], $sorted); | ||
|
||
$sorted = Sorting::sortObjectsByProperty( | ||
[$sortable1, $sortable2, $sortable3, $sortable4], 'date' | ||
); | ||
|
||
static::assertSame([$sortable4, $sortable3, $sortable1, $sortable2], $sorted); | ||
} | ||
} |