У меня есть этот массив:
$routes = array( array( 'code' => 'PZSA', 'name' => 'PLaza san antonio', ), array( 'code' => 'AVAD', 'name' => 'Av de asturias', ), array( 'code' => 'AVAR', 'name' => 'Av simon nieto', ) );
И я хочу отсортировать его на основе следующих ключей:
$target = array('AVAD', 'AVAR', 'PZSA');
Таким образом, отсортированный массив будет:
Array ( [0] => Array ( [code] => AVAD [name] => Av de asturias ) [1] => Array ( [code] => AVAR [name] => Av simon nieto ) [2] => Array ( [code] => PZSA [name] => PLaza san antonio ) )
Я пробовал это, и это работает, но я думаю, что это слишком много кода для этой простой вещи. Любые альтернативы? Благодарю.
function _sort($array, $orderArray) { $ordered = array(); foreach ($orderArray as $key) { $ordered[] = find($key, $array); } return $ordered; } function find($code, $routes) { foreach ($routes as $key => $value) { if ($routes[$key]['code'] == $code) { return $routes[$key]; } } } $sorted = _sort($routes, $target);
$target_flip = array_flip($target); usort($routes, function($a, $b) use ($target_flip){ return ($target_flip[$a['code']] < $target_flip[$b['code']]) ? -1 : 1; });
Демо-версия:
Docs:
Вместо того, чтобы делать то, что по существу является линейным поиском для каждого элемента, может быть проще всего переиндексировать исходный массив по коду:
// create the index $indexed = array(); foreach($routes as $route) { $indexed[$route['code']] = $route; } // add each target to a new sorted array in order $sorted = array(); foreach($target as $code) { $sorted[] = $indexed[$code]; }
Это то, что array_multisort
если для:
foreach ($routes as $key => $row) { $code[$key] = $row['code']; $name[$key] = $row['name']; } array_multisort($code, SORT_ASC, $name, SORT_ASC, $routes); print_r( $routes );
Таким образом, вам даже не нужен второй массив!
Фактически в вашем случае вам нужно только сортировать коды, чтобы это сделало трюк:
foreach ($routes as $key => $row) { $code[$key] = $row['code']; } array_multisort($code, SORT_ASC, $routes);
Несколько более общее решение, в котором вы можете просто установить ключ, который хотите отсортировать, и он должен работать для любого многомерного массива.
//key to sort by $sortBy = 'code'; $sorted = array(); foreach($routes as $route) { foreach($route as $key => $value) { if(!isset($sorted[$key])) { $sorted[$key] = array(); } $sorted[$key][] = $value; } } array_multisort($sorted[$sortBy], SORT_ASC, $routes); print_r($routes)
В качестве альтернативы уже упомянутым ответам (за исключением Питера) вы можете использовать свою логику с помощью uasort()
. Сначала вам нужно определить функцию сравнения (сравнить $ a до $ b) и построить логику с использованием значений -1
, 0
и 1
чтобы решить, должна ли сравниваемая строка идти до, после или оставаться неизменной.
// This sorts simply by alphabetic order function reindex( $a, $b ) { // Here we grab the values of the 'code' keys from within the array. $val1 = $a['code']; $val2 = $b['code']; // Compare string alphabetically if( $val1 > $val2 ) { return 1; } elseif( $val1 < $val2 ) { return -1; } else { return 0; } } // Call it like this: uasort( $routes, 'reindex' ); print_r( $routes );
Конечно, это работает только в качестве небольшого примера, и если вы пытаетесь индексировать их в алфавитном порядке. Если вам нужно сортировать по точному набору ключей, а не в алфавитном порядке, это может быть немного сложнее, поскольку оно не принимает никаких других параметров.
PHP uasort () Ссылка