Add methods to sort collections

master
Julien Rosset 2 years ago
parent 22cc1b439f
commit 593e118ba1

@ -15,7 +15,8 @@
"minimum-stability": "stable", "minimum-stability": "stable",
"require": { "require": {
"php": "^8.1" "php": "^8.1",
"sgh/comparable": "^1.1"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {

@ -7,6 +7,9 @@ use Closure;
use Countable; use Countable;
use IteratorAggregate; use IteratorAggregate;
use JsonSerializable; use JsonSerializable;
use SGH\Comparable\Comparable;
use SGH\Comparable\Comparator;
use Throwable;
/** /**
* Interface for an immutable (read-only) collection * Interface for an immutable (read-only) collection
@ -125,6 +128,34 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Coun
*/ */
public function map (Closure $process): self; public function map (Closure $process): self;
/**
* Sort the elements (by value)
*
* @param null|Comparator|Closure(TValue, TValue):int $sorter The sorting method ; Null if values are object implementing {@see Comparable}.
* <br>Return :
* <br>&lt; 0 if value1 is before value2
* <br>= 0 if value1 equals value2
* <br>&gt; 0 if value1 is after value2
*
* @return self The sorted collection
*
* @throws Throwable If an error occurs
*/
public function sort (Closure|Comparator|null $sorter = null): self;
/**
* Sort the elements by key
*
* @param Comparator|Closure(TKey, TKey):int $sorter The sorting method. Return :
* <br>&lt; 0 if key1 is before key2
* <br>= 0 if key1 equals key2
* <br>&gt; 0 if key1 is after key2
*
* @return self The sorted collection
*
* @throws Throwable If an error occurs
*/
public function sortByKey (Closure|Comparator $sorter): self;
/** /**
* The list of all keys * The list of all keys
* *
@ -163,7 +194,7 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Coun
* *
* @param IImmutableCollection ...$collections The other collections to combine * @param IImmutableCollection ...$collections The other collections to combine
* *
* @return static The combine collection * @return static The combined collection
*/ */
public function combineWith (IImmutableCollection ...$collections): self; public function combineWith (IImmutableCollection ...$collections): self;
} }

@ -5,6 +5,8 @@ namespace jrosset\Collections;
use ArrayIterator; use ArrayIterator;
use Closure; use Closure;
use InvalidArgumentException; use InvalidArgumentException;
use SGH\Comparable\Comparable;
use SGH\Comparable\Comparator;
use Traversable; use Traversable;
/** /**
@ -46,7 +48,7 @@ class ImmutableCollection implements IImmutableCollection {
* @throws InvalidArgumentException If the initial values aren't valid * @throws InvalidArgumentException If the initial values aren't valid
* @internal * @internal
*/ */
protected function _initialize (?iterable $other = null) { protected function _initialize (?iterable $other = null): void {
$this->elements = []; $this->elements = [];
if ($other !== null) { if ($other !== null) {
if (!is_array($other) && !$other instanceof Traversable) { if (!is_array($other) && !$other instanceof Traversable) {
@ -300,6 +302,42 @@ class ImmutableCollection implements IImmutableCollection {
return $output; return $output;
} }
/**
* @inheritDoc
*/
public function sort (Closure|Comparator|null $sorter = null): static {
if ($sorter === null) {
$sorter = function (Comparable $value1, Comparable $value2): int {
return $value1->compareTo($value2);
};
}
elseif ($sorter instanceof Comparator) {
$sorter = function ($value1, $value2) use ($sorter): int {
return $sorter->compare($value1, $value2);
};
}
$elements = $this->toArray();
uasort($elements, $sorter);
return new static($elements);
}
/**
* @inheritDoc
*/
public function sortByKey (Closure|Comparator $sorter): static {
if ($sorter instanceof Comparator) {
$sorter = function ($value1, $value2) use ($sorter): int {
return $sorter->compare($value1, $value2);
};
}
$elements = $this->toArray();
uksort($elements, $sorter);
return new static($elements);
}
/** /**
* @inheritDoc * @inheritDoc
*/ */

Loading…
Cancel
Save