mirror of
https://github.com/Shadowss/TravianZ.git
synced 2026-08-09 12:51:01 +00:00
Fix lexicographic multi-key sorting (#356)
This commit is contained in:
+48
-38
@@ -30,57 +30,67 @@ class multiSort
|
||||
{
|
||||
$args = func_get_args();
|
||||
$array = $args[0];
|
||||
$criteria = array();
|
||||
|
||||
// iterate key/order/type triplets
|
||||
// Collect key/order/type triplets in their declared priority order.
|
||||
for ($i = 1; $i < count($args); $i += 3)
|
||||
{
|
||||
$key = isset($args[$i]) ? $args[$i] : null;
|
||||
$order = isset($args[$i + 1]) ? $args[$i + 1] : true; // true = ASC
|
||||
$type = isset($args[$i + 2]) ? $args[$i + 2] : 0;
|
||||
|
||||
if ($key === null) {
|
||||
continue;
|
||||
if ($key !== null) {
|
||||
$criteria[] = array($key, $order, $type);
|
||||
}
|
||||
|
||||
// comparator
|
||||
$cmp = function ($a, $b) use ($key, $type, $order)
|
||||
{
|
||||
$va = isset($a[$key]) ? $a[$key] : null;
|
||||
$vb = isset($b[$key]) ? $b[$key] : null;
|
||||
|
||||
switch ($type)
|
||||
{
|
||||
case 1: // Case insensitive natural
|
||||
$result = strnatcasecmp($va, $vb);
|
||||
break;
|
||||
|
||||
case 2: // Numeric
|
||||
$result = ($va == $vb) ? 0 : (($va < $vb) ? -1 : 1);
|
||||
break;
|
||||
|
||||
case 3: // Case sensitive string
|
||||
$result = strcmp((string)$va, (string)$vb);
|
||||
break;
|
||||
|
||||
case 4: // Case insensitive string
|
||||
$result = strcasecmp((string)$va, (string)$vb);
|
||||
break;
|
||||
|
||||
default: // Case sensitive natural
|
||||
$result = strnatcmp((string)$va, (string)$vb);
|
||||
break;
|
||||
}
|
||||
|
||||
return $order ? $result : -$result;
|
||||
};
|
||||
|
||||
usort($array, $cmp);
|
||||
}
|
||||
|
||||
if (!count($criteria)) {
|
||||
return $array;
|
||||
}
|
||||
|
||||
usort($array, function ($a, $b) use ($criteria) {
|
||||
foreach ($criteria as $criterion) {
|
||||
list($key, $order, $type) = $criterion;
|
||||
$va = isset($a[$key]) ? $a[$key] : null;
|
||||
$vb = isset($b[$key]) ? $b[$key] : null;
|
||||
$result = $this->compareValues($va, $vb, $type);
|
||||
|
||||
if ($result !== 0) {
|
||||
return $order ? $result : -$result;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two values using the sort type expected by sorte().
|
||||
*/
|
||||
private function compareValues($a, $b, $type)
|
||||
{
|
||||
switch ($type)
|
||||
{
|
||||
case 1: // Case insensitive natural
|
||||
return strnatcasecmp((string)$a, (string)$b);
|
||||
|
||||
case 2: // Numeric
|
||||
return ($a == $b) ? 0 : (($a < $b) ? -1 : 1);
|
||||
|
||||
case 3: // Case sensitive string
|
||||
return strcmp((string)$a, (string)$b);
|
||||
|
||||
case 4: // Case insensitive string
|
||||
return strcasecmp((string)$a, (string)$b);
|
||||
|
||||
default: // Case sensitive natural
|
||||
return strnatcmp((string)$a, (string)$b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$multisort = new multiSort();
|
||||
|
||||
?>
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user