src/Utils.php
public static function stableSort(array $elements, callable $getComparedValue, callable $compareValues)
    {
        array_walk($elements, static function (&$element, $index) use ($getComparedValue) {
            $element = [$element, $index, $getComparedValue($element)];
        });

        usort($elements, static function ($a, $b) use ($compareValues) {
            $comparison = $compareValues($a[2], $b[2]);

            if (0 !== $comparison) {
                return $comparison;
            }

            return self::cmpInt($a[1], $b[1]);
        });

        return array_map(static function (array $item) {
            return $item[0];
        }, $elements);
    }
public static function stableSort(array $elements, callable $getComparedValue, callable $compareValues)
    {
        array_walk($elements, static function (&$element, $index) use ($getComparedValue) {
            $element = [$element, $index, $getComparedValue($element)];
        });

        usort($elements, static function ($a, $b) use ($compareValues) {
            $comparison = $compareValues($a[2], $b[2]);

            if (0 !== $comparison) {
                return $comparison;
            }

            return self::cmpInt($a[1], $b[1]);
        });

        return array_map(static function (array $item) {
            return $item[0];
        }, $elements);
    }
Perform stable sorting using provided comparison function.

Stability is ensured by using Schwartzian transform.

@param mixed[]  $elements
@param callable $getComparedValue a callable that takes a single element and returns the value to compare
@param callable $compareValues    a callable that compares two values

@return mixed[]