Оптимизация изменения порядка и удаления дубликатов многомерного массива

#php #optimization #multidimensional-array #array-multisort

#php #оптимизация #многомерный массив #массив-мультисортировка

Вопрос:

Мне интересно, есть ли у кого-нибудь хорошие идеи по оптимизации следующего кода. У меня есть многомерный массив ($ List) следующим образом:

 Array
(
    [0] => Array
    (
        [id] => 1
        [title] => A good read
        [priority] => 10
    )

    [1] => Array
    (
        [id] => 2
        [title] => A bad read
        [priority] => 20

    )

    [2] => Array
    (
        [id] => 3
        [title] => A good read
        [priority] => 10
    )
)
  

Сначала я удаляю все записи с одинаковым заголовком (независимо от того, каковы другие значения) следующим образом:

 $List_new = array();
foreach ($List as $val) {
    $List_new[$val['title']] = $val;    
}
$List = array_values($List_new);
  

Идеальный. Затем я переупорядочиваю массив, сначала по полю приоритета, а затем по идентификатору:

 $sort_id = array();
$sort_priority = array();
foreach ($List as $key => $row) {
    $sort_id[$key] = $row['id'];
    $sort_priority[$key] = $row['priority'];
}
array_multisort($sort_priority, SORT_DESC, $sort_id, SORT_DESC, $List);
  

Оба блока кода появляются в цикле, отсюда очистка $sort_id и $ sort_priority перед переупорядочением.

Есть ли лучший способ сделать это — т. Е. использовать процесс сортировки для удаления дублирующихся записей заголовка? Этот блок кода выполняется в цикле, содержащем до 500 000 записей, и поэтому любые улучшения будут приветствоваться!

Ответ №1:

Один цикл, но несколько дополнительных вызовов функций, поэтому я не могу сказать вам, как меняется Big O. Следует отметить одну вещь: отступы вокруг чисел должны быть достаточно большими, чтобы предотвратить переполнение, т.е. 2 = максимум 99 приоритетов и 6 = максимум 999 999 элементов.

 $list_titles = array();
foreach($List as $val) {
    if(isset($list_titles[$val['title']])) continue;
    $list_titles[$val['title']] = true;
    $List_new[str_pad($val['priority'], 2, 0, STR_PAD_LEFT).str_pad($val['id'], 6, 0, STR_PAD_LEFT)] = $val;
}
krsort($List_new);
  

Редактировать: внесены некоторые незначительные изменения.