Skip to content

Commit cab8223

Browse files
committed
Added sortObjects method
1 parent f5db686 commit cab8223

File tree

3 files changed

+84
-1
lines changed

3 files changed

+84
-1
lines changed

README.md

+29
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Here, you can quickly get started by becoming familiar with each and every metho
6666
* Ordering
6767
* [orderByKeys](#orderbykeysarray-array-mixed-keys-bool-appendunmatched--true-array)
6868
* [sortByKeys](#sortbykeysarray-array-mixed-keys--null-bool-assoc--true-array)
69+
* [sortObjects](#sortobjectsarray-objects-string-method-args-array)
6970
* Computations
7071
* [sum](#sumarray-arrays-array)
7172
* [diffObjects](#diffobjectsarray-array1-array-array2-array-arrays-array)
@@ -536,6 +537,34 @@ Arr::sortByKeys(['a' => 3, 'b' => 1, 'c' => 6]) -> ['b' => 1, 'a' => 3, 'c' => 6
536537
Arr::sortByKeys(['a' => 3, 'b' => 1, 'c' => 6], null, false) -> [1, 3, 6]
537538
```
538539

540+
### `sortObjects(array $objects, string $method, ...$args): array`
541+
Sort array of objects by comparing result of supplied method name
542+
543+
`$object1->$method(...$args) <=> $object2->$method(...$args)`
544+
545+
```php
546+
$object1 = new class() {
547+
function getValue() {
548+
return 1;
549+
}
550+
};
551+
$object2 = new class() {
552+
function getValue(bool $reverse = false) {
553+
return $reverse ? 1/2 : 2;
554+
}
555+
};
556+
$object3 = new class() {
557+
function getValue(bool $reverse = false) {
558+
return $reverse ? 1/3 : 3;
559+
}
560+
};
561+
562+
$array = [$object2, $object3, $object1];
563+
564+
Arr::sortObjects($array, 'getValue') -> [$object1, $object2, $object3]
565+
Arr::sortObjects($array, 'getValue', true) -> [$object3, $object2, $object1]
566+
```
567+
539568
## Computations
540569

541570
### `sum(array ...$arrays): array`

src/Arr.php

+20-1
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ public static function orderByKeys(array $array, $keys, bool $appendUnmatched =
553553
* @param array $array Array of arrays
554554
* @param mixed $keys Keys in format specified by getKeysArray method or null to perform sort using 0-depth keys
555555
* @param bool $assoc If sorting should preserve main array keys (default: true)
556-
* @return array Sorted array
556+
* @return array New sorted array
557557
* @see \Minwork\Helper\Arr::getKeysArray()
558558
*/
559559
public static function sortByKeys(array $array, $keys = null, bool $assoc = true): array
@@ -568,6 +568,25 @@ public static function sortByKeys(array $array, $keys = null, bool $assoc = true
568568
return $return;
569569
}
570570

571+
/**
572+
* Sort array of objects using result of calling supplied method name on object as value to compare
573+
*
574+
* @param array $objects Array of objects
575+
* @param string $method Name of a method called for every array element (object) in order to obtain value to compare
576+
* @param mixed ...$args Arguments for method
577+
* @return array New sorted array
578+
*/
579+
public static function sortObjects(array $objects, string $method, ...$args): array
580+
{
581+
$result = $objects;
582+
583+
uasort($result, function ($a, $b) use ($method, $args) {
584+
return $a->$method(...$args) <=> $b->$method(...$args);
585+
});
586+
587+
return $result;
588+
}
589+
571590
/**
572591
* Sum associative arrays by their keys into one array
573592
*

test/ArrTest.php

+35
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,41 @@ public function testSortByKeys()
599599
], Arr::sortByKeys($array3, 'b.c', false));
600600
}
601601

602+
public function testSortObjects()
603+
{
604+
$object1 = new class() {
605+
public static $counter = 1;
606+
public $i = 1;
607+
608+
public function __clone()
609+
{
610+
$this->i = ++self::$counter;
611+
}
612+
613+
public function getValue(bool $reverse = false) {
614+
return $reverse ? 1 / $this->i : $this->i;
615+
}
616+
};
617+
$object2 = clone $object1;
618+
$object3 = clone $object1;
619+
$object4 = clone $object1;
620+
$object5 = clone $object1;
621+
622+
$proto = [$object1, $object2, $object3, $object4, $object5];
623+
$array = $proto;
624+
625+
$this->assertSame(Arr::mapObjects($array, 'getValue'), [1, 2, 3, 4, 5]);
626+
$this->assertSame(Arr::mapObjects($array, 'getValue', true), [1, 1/2, 1/3, 1/4, 1/5]);
627+
628+
// Ensure order is not the same
629+
do {
630+
$array = Arr::shuffle($array);
631+
} while ($array === $proto);
632+
633+
$this->assertSame($proto, Arr::sortObjects($array, 'getValue'));
634+
$this->assertSame(array_reverse($proto, true), Arr::sortObjects($array, 'getValue', true));
635+
}
636+
602637
public function testSum()
603638
{
604639
$arrays = [

0 commit comments

Comments
 (0)