diff --git a/src/Collections/IComparable.php b/src/Collections/IComparable.php
new file mode 100644
index 0000000..33ba7b8
--- /dev/null
+++ b/src/Collections/IComparable.php
@@ -0,0 +1,23 @@
+< 0 if current instance is classed before the other instance
+ *
= 0 if current instance is classed equals the other instance
+ *
> 0 if current instance is classed after the other instance
+ *
+ * @noinspection PhpMissingParamTypeInspection
+ */
+ public function compareTo ($other): int;
+}
\ No newline at end of file
diff --git a/src/Collections/IComparator.php b/src/Collections/IComparator.php
new file mode 100644
index 0000000..c63e67e
--- /dev/null
+++ b/src/Collections/IComparator.php
@@ -0,0 +1,24 @@
+< 0 if the first object is classed before the second object
+ *
= 0 if the first object is classed equals the second object
+ *
> 0 if the first object is classed after the second object
+ *
+ * @noinspection PhpMissingParamTypeInspection
+ */
+ public function compare ($object1, $object2): int;
+}
\ No newline at end of file
diff --git a/src/Collections/IImmutableCollection.php b/src/Collections/IImmutableCollection.php
index 45a74ea..9c03f17 100644
--- a/src/Collections/IImmutableCollection.php
+++ b/src/Collections/IImmutableCollection.php
@@ -8,6 +8,7 @@ use Countable;
use IteratorAggregate;
use JsonSerializable;
use Serializable;
+use Throwable;
/**
* Interface for an immutable (read-only) collection
@@ -126,6 +127,40 @@ interface IImmutableCollection extends IteratorAggregate, JsonSerializable, Seri
*/
public function map (Closure $process): self;
+ /**
+ * Sort the elements (by value)
+ *
+ * @param null|IComparator|Closure(TValue, TValue):int $sorter The sorting method ; Null if values are object implementing {@see IComparable}.
+ *
Return :
+ *
< 0 if value1 is before value2
+ *
= 0 if value1 equals value2
+ *
> 0 if value1 is after value2
+ *
+ * @return static The sorted collection
+ * @psalm-return static
+ *
+ * @throws Throwable If an error occurs
+ *
+ * @noinspection PhpMissingReturnTypeInspection
+ */
+ public function sort ($sorter = null);
+ /**
+ * Sort the elements by key
+ *
+ * @param IComparator|Closure(TKey, TKey):int $sorter The sorting method. Return :
+ *
< 0 if key1 is before key2
+ *
= 0 if key1 equals key2
+ *
> 0 if key1 is after key2
+ *
+ * @return static The sorted collection
+ * @psalm-return static
+ *
+ * @throws Throwable If an error occurs
+ *
+ * @noinspection PhpMissingReturnTypeInspection
+ */
+ public function sortByKey ($sorter);
+
/**
* The list of all keys
*
diff --git a/src/Collections/ImmutableCollection.php b/src/Collections/ImmutableCollection.php
index e358d87..74d636d 100644
--- a/src/Collections/ImmutableCollection.php
+++ b/src/Collections/ImmutableCollection.php
@@ -294,6 +294,42 @@ class ImmutableCollection implements IImmutableCollection {
return $output;
}
+ /**
+ * @inheritDoc
+ */
+ public function sort ($sorter = null) {
+ if ($sorter === null) {
+ $sorter = function (IComparable $value1, IComparable $value2): int {
+ return $value1->compareTo($value2);
+ };
+ }
+ elseif ($sorter instanceof IComparator) {
+ $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 ($sorter) {
+ if ($sorter instanceof IComparator) {
+ $sorter = function ($value1, $value2) use ($sorter): int {
+ return $sorter->compare($value1, $value2);
+ };
+ }
+
+ $elements = $this->toArray();
+ uksort($elements, $sorter);
+
+ return new static($elements);
+ }
+
/**
* @inheritDoc
*/
diff --git a/tests/test_class.php b/tests/test_class.php
index 77cbd71..837f4db 100644
--- a/tests/test_class.php
+++ b/tests/test_class.php
@@ -1,11 +1,19 @@
+ */
+class Measure implements IComparable {
private int $value;
private string $unit;
@@ -14,9 +22,33 @@ class Measure {
$this->unit = $unit;
}
+ public function getValue (): int {
+ return $this->value;
+ }
+
public function asString (): string {
return $this->value . $this->unit;
}
+
+ /**
+ * @inheritDoc
+ */
+ public function compareTo ($other): int {
+ return $this->value <=> $other->value;
+ }
+}
+/**
+ * Class MeasureReverseComparator
+ *
+ * @implements IComparator
+ */
+class MeasureReverseComparator implements IComparator {
+ /**
+ * @inheritDoc
+ */
+ public function compare ($object1, $object2): int {
+ return -($object1->getValue() <=> $object2->getValue());
+ }
}
/**
@@ -34,6 +66,11 @@ function getMeasures (): Collection {
}
echo 'Measures :' . PHP_EOL;
-foreach (getMeasures() as $no => $measure) {
+foreach (getMeasures()->sort() as $no => $measure) {
+ echo "\t#" . $no . ' = ' . $measure->asString() . PHP_EOL;
+}
+
+echo 'Measures (reversed) :' . PHP_EOL;
+foreach (getMeasures()->sort(new MeasureReverseComparator()) as $no => $measure) {
echo "\t#" . $no . ' = ' . $measure->asString() . PHP_EOL;
}
\ No newline at end of file