$items * @param callable(TValue): (int|float|string) $keyFn * @return list */ public static function sort(array $items, callable $keyFn, bool $descending = false): array { $copy = array_values($items); usort($copy, static function ($a, $b) use ($keyFn, $descending): int { $ka = $keyFn($a); $kb = $keyFn($b); $cmp = is_string($ka) ? strcmp((string) $ka, (string) $kb) : ($ka <=> $kb); return $descending ? -$cmp : $cmp; }); return $copy; } }