PHP - сортировка многомерного массива по другому массиву - PullRequest
7 голосов
/ 19 октября 2011

Я пытаюсь отсортировать многомерный массив по другому массиву, но пока не дотягивает до конца.
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'),
);

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

Ответы [ 4 ]

7 голосов
/ 19 октября 2011

В вашем примере идентификаторы в массиве $ 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).Вы не можете сделать лучше.

5 голосов
/ 19 октября 2011

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

$sorted = array_map(function($v) use ($data) {
    return $data[$v - 1];
}, $order);
0 голосов
/ 12 марта 2017

Это было бы так, как я бы сделал.Я бы использовал пользовательскую функцию 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>";
0 голосов
/ 19 октября 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...