PHP – Сортировка многомерного массива другим массивом

Я пытаюсь сортировать многомерный массив с помощью другого массива, но до сих пор это не так.
array_multisort похоже, работает только для реальной сортировки.

Предположим, у меня есть эти 2 массива:

 $order = array(2,3,1); $data = array( array('id' => 1, 'title' => 'whatever'), array('id' => 2, 'title' => 'whatever'), array('id' => 3, 'title' => 'whatever') ); 

Теперь я хотел бы отсортировать массив $data соответствии с порядком в моем массиве $order .
Это то, что я хотел бы получить:

 $data = array( array('id' => 2, 'title' => 'whatever'), array('id' => 3, 'title' => 'whatever') array('id' => 1, 'title' => 'whatever'), ); 

Я могу сделать это легко, запустив вложенный цикл, но это не будет хорошо масштабироваться (мой массив довольно большой, а в массивах больше полей).

В PHP нет встроенной функции, и я не могу думать о какой-либо пользовательской функции, которая будет делать это с помощью usort. Но array_map достаточно прост, imo, так почему бы не использовать его вместо этого?

 $sorted = array_map(function($v) use ($data) { return $data[$v - 1]; }, $order); 

В вашем примере идентификаторы в массиве $ data нумеруются последовательно и начинаются с 1. Код, который я даю ниже, предполагает, что это всегда так. Если это не так, код не работает.

 $result = array(); $index = 0; foreach ($order as $position) { $result[$index] = $data[$position - 1]; $index++; } 

На странице http://codepad.org/YC8w0yHh вы можете видеть, что он работает для ваших данных примера.

РЕДАКТИРОВАТЬ

Если упомянутое выше предположение не выполняется, следующий код достигнет того же результата:

 <?php $data = array( array('id' => 1, 'title' => 'whatever'), array('id' => 2, 'title' => 'whatever'), array('id' => 3, 'title' => 'whatever') ); $order = array(2,3,1); $order = array_flip($order); function cmp($a, $b) { global $order; $posA = $order[$a['id']]; $posB = $order[$b['id']]; if ($posA == $posB) { return 0; } return ($posA < $posB) ? -1 : 1; } usort($data, 'cmp'); var_dump($data); 

См. http://codepad.org/Q7EcTSfs для подтверждения.

Вызывая array_flip () в массиве $ order, он может использоваться для поиска позиции. Это похоже на поиск хеш-таблицы, который является линейным по времени или O (n). Вы не можете сделать лучше.

Вы можете попробовать использовать пользовательский сортировку с помощью функции usort () . Таким образом, вы можете использовать первый массив для определения порядка второго массива.

Я бы это сделал. Я бы использовал пользовательскую функцию usort (arr_sort) в сочетании с массивом $ data.

 <?php $order = array(2,3,1); $data = array( array('id' => 1, 'title' => 'whatever'), array('id' => 2, 'title' => 'whatever'), array('id' => 3, 'title' => 'whatever') ); function arr_sort($a,$b){ global $order; foreach ($order as $key => $value) { if ($value==$a['id']) { return 0; break; } if ($value==$b['id']) { return 1; break; } } } usort($data,'arr_sort'); echo "<pre>"; print_r($data); echo "<pre>";