<?php
function sanitizeColumnReference($row, $columnReference) {
if (!isset($row[$columnReference]) && is_int($columnReference)) {
$columnReference = array_keys($row)[$columnReference] ?? null; // attempt to derive column name by position
if ($columnReference === null) {
throw new Exception('Failed to locate column by position using column reference: ' . $columnReference);
}
}
return $columnReference;
}
function dynamicSort(&$input, $sortingRules) {
if (!$input || !$sortingRules || !is_array($input) || !is_array($sortingRules)) {
return; // return silently
}
$firstRow = current($input);
$sortingParams = [];
foreach ($sortingRules as $rule) {
$rule = (array)$rule; // permit the passing of a solitary string as a sorting rule
$columnReference = sanitizeColumnReference($firstRow, array_shift($rule));
$column = array_column($input, $columnReference);
if (!$column) {
throw new Exception('Failed to source sortable data from column reference: ' . $columnReference);
}
$sortingParams[] = $column;
foreach ($rule as $flag) {
$sortingParams[] = constant('SORT_' . strtoupper($flag)); // convert strings to usable CONSTANTs
}
}
$sortingParams[] = &$input;
var_export($sortingParams);
array_multisort(...$sortingParams); // unpack into native sorting function
}
$array = [
['first_name' => 'Homer', 'last_name' => 'Simpson', 'city' => 'Springfield', 'state' => 'Unknown', 'zip' => '66735'],
['first_name' => 'Patty', 'last_name' => 'Bouvier', 'city' => 'Scottsdale', 'state' => 'Arizona', 'zip' => '85250'],
['first_name' => 'Moe', 'last_name' => 'Szyslak', 'city' => 'Scottsdale', 'state' => 'Arizona', 'zip' => '85255'],
['first_name' => 'Nick', 'last_name' => 'Riviera', 'city' => 'Scottsdale', 'state' => 'Arizona', 'zip' => '85255'],
];
$sortingRules = [
'city',
['zip', 'desc', 'numeric'],
[1, 'desc'], // last_name
];
echo "Sorting Params:\n";
dynamicSort($array, $sortingRules); // this modifies by reference like native sorting functions
echo "\n---\nOutput:\n";
var_export($array);
preferences:
107.99 ms | 412 KiB | 5 Q