Я пытаюсь сделать то же самое, что и mySQL-запрос «SELECT * FROM table ORDER BY field1, field2, …» с многомерным массивом:
$Test = array( array("a"=>"004", "n"=>"03"), array("a"=>"003", "n"=>"02"), array("a"=>"001", "n"=>"02"), array("a"=>"005", "n"=>"01"), array("a"=>"001", "n"=>"01"), array("a"=>"004", "n"=>"02"), array("a"=>"003", "n"=>"01"), array("a"=>"004", "n"=>"01") ); function msort(&$array, $keys){ array_reverse($keys); foreach($keys as $key){ uasort($array, sortByKey); } // function sortByKey($A, $B){ global $key; $a = $A[$key]; $b = $B[$key]; if($a==$b) return 0; return ($a < $b)? -1 : 1 ; } } // msort($Test, array("a","n")); // foreach($Test as $t){ echo('<p>'.$t["a"].'-'.$t["n"].'</p>'); }
Моя теория такова: если я сортирую умножить время на менее важный ключ к самому важному ключу, я закажу такой запрос mySQL.
Но php возвращает «Warning: uasort () ожидает, что параметр 2 будет действительным обратным вызовом, функция« sortByKey »не найдена или неверное имя функции в /Library/WebServer/Documents/www/teste.array_sort.php в строке 23» (uasort линия)
Это простая функция заказа, чего мне не хватает?
В принципе, мы будем использовать тот же подход, что и здесь , мы просто будем делать это с помощью переменного количества ключей:
/** * Returns a comparison function to sort by $cmp * over multiple keys. First argument is the comparison * function, all following arguments are the keys to * sort by. */ function createMultiKeyCmpFunc($cmp, $key /* , keys... */) { $keys = func_get_args(); array_shift($keys); return function (array $a, array $b) use ($cmp, $keys) { return array_reduce($keys, function ($result, $key) use ($cmp, $a, $b) { return $result ?: call_user_func($cmp, $a[$key], $b[$key]); }); }; } usort($array, createMultiKeyCmpFunc('strcmp', 'foo', 'bar', 'baz')); // or usort($array, createMultiKeyCmpFunc(function ($a, $b) { return $a - $b; }, 'foo', 'bar', 'baz'));
Это примерно эквивалентно SQL ORDER BY foo, bar, baz
.
Если, конечно, каждый ключ требует различной логики сравнения, и вы не можете использовать общие strcmp
или -
для всех, вы вернетесь к тому же коду, что и объяснено здесь .
Вот код, который я написал, чтобы сделать что-то подобное:
uasort($array,function($a,$b) { return strcmp($a['launch'],$b['launch']) ?: strcmp($a['tld'],$b['tld']) ?: strcmp($a['sld'],$b['sld']); });
Это как бы злоупотребляет тем фактом, что отрицательные числа являются правдивыми (только ноль – ложный), чтобы сначала сравнить launch
, затем tld
, затем sld
. Вы должны быть в состоянии адаптировать это к вашим потребностям достаточно легко.
Это сделает работу, спасибо за вклад!
function mdsort(&$array, $keys){ global $KeyOrder; $KeyOrder = $keys; uasort($array, cmp); } function cmp(array $a, array $b) { global $KeyOrder; foreach($KeyOrder as $key){ $res = strcmp($a[$key], $b[$key]); if($res!=0) break; } return $res; } // mdsort($Test, array("a","n"));
Этот код немного уродлив, хотя я считаю, что это может быть лучше – может быть, класс для решения проблемы передачи массива с помощью клавиш «cmp». Но это начальная точка, вы можете использовать ее с любым количеством ключей для сортировки.