2016-02-23 3 views
3

У меня есть мульти двумерный массив так:Сортировка многомерные массив по 3 значений, или разбить массив на 3 массивов по значению

maildate | mag | panel | status 
2-22-16 | green | 1 | pending 
2-22-16 | green | 3 | completed 
2-22-16 | green | 2 | working 
2-23-16 | red | 1 | pending 
2-22-16 | blue | 1 | complete 

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

// function to sort mulitdimensional array by key 
function array_sort($array, $on, $order=SORT_ASC){ 
    $new_array = array(); 
    $sortable_array = array(); 
    if (count($array) > 0) { 
     foreach ($array as $k => $v) { 
      if (is_array($v)) { 
       foreach ($v as $k2 => $v2) { 
        if ($k2 == $on) { 
         $sortable_array[$k] = $v2; 
        } 
       } 
      } else { 
      $sortable_array[$k] = $v; 
     } 
    } 
    switch ($order) { 
     case SORT_ASC: 
      asort($sortable_array); 
      break; 
     case SORT_DESC: 
      arsort($sortable_array); 
      break; 
    } 
    foreach ($sortable_array as $k => $v) { 
     $new_array[$k] = $array[$k]; 
    } 
} 
return $new_array; 
} 
// sort lblist array by status 
$lblist = array_sort($lblist, 'status', SORT_ASC); 

У меня также есть эта функция, которая, похоже, работает, но группы статуса разделяются.

function sortByOrder($a, $b){ 
if ($b['status'] == $a['status']) { 
if ($b['maildate'] == $a['maildate']) { 
    if ($b['mag'] == $a['mag']) { 
     return $b['panel'] - $a['panel']; 
     } 
    else { 
     return $b['mag'] - $a['mag']; 
     } 
    } 
else { 
    return $b['maildate'] - $a['maildate']; 
    } 
} 
else { 
return $b['status'] - $a['status']; 
} 
} 
usort($lblist, 'sortByOrder'); 

Я подумал, может разделить массив по статусу, как только это своего рода тем, чтобы держать их вместе, а затем делать другие виды на каждом «югу» массив.

ответ

1

Рассмотрите возможность использования array_multisort() но сначала захватывая внутренние массивы:

// RECREATE ARRAY  
$mail = array(); 
$mail[0]['maildate'] = '2-22-16'; $mail[0]['mag'] = 'green'; $mail[0]['panel'] = 1; $mail[0]['status'] = 'pending'; 
$mail[1]['maildate'] = '2-22-16'; $mail[1]['mag'] = 'green'; $mail[1]['panel'] = 3; $mail[1]['status'] = 'completed'; 
$mail[2]['maildate'] = '2-22-16'; $mail[2]['mag'] = 'green'; $mail[2]['panel'] = 2; $mail[2]['status'] = 'working'; 
$mail[3]['maildate'] = '2-23-16'; $mail[3]['mag'] = 'red'; $mail[3]['panel'] = 1; $mail[3]['status'] = 'pending'; 
$mail[4]['maildate'] = '2-22-16'; $mail[4]['mag'] = 'blue'; $mail[4]['panel'] = 1; $mail[4]['status'] = 'completed'; 

$maildate = array(); 
$mag = array(); 
$panel = array(); 
$status = array(); 

// CAPTURE INNER ARRAYS 
foreach ($mail as $rows) { 
    foreach ($rows as $key => $value) { 
     switch ($key) { 
      case 'maildate': $maildate[] = date_create_from_format('m-d-y', $value)->format('Y-m-d'); break; 
      case 'mag': $mag[] = $value; break; 
      case 'panel': $panel[] = $value; break; 
      case 'status': $status[] = $value; break; 
     } 
    } 
} 

// APPLY MULTIPLE SORTS TO MAIN ARRAY 
array_multisort($status, SORT_ASC, $maildate, SORT_ASC, 
       $mag, SORT_ASC, $panel, SORT_ASC, $mail); 
+0

Отлично. Благодарю. –

1

Оглядываясь назад на массив в вопросе (хотя это текст, а не фактический код), вы, вероятно, захотите его нормализовать. Попробуйте это до рода:

foreach($lblist as $row) { 
    $array[] = array_combine($lblist[0], $row); 
} 

Таким образом, вы можете извлечь каждый из столбцов и сортировки на тех, в порядке и отсортировать исходный массив на основе этого порядка. Обратите внимание, что maildate необходимо преобразовать в метку времени для правильной сортировки и mm-dd-YY недействителен с тире -. Черточки используют dd-mm-YY, поэтому вам нужно / для mm/dd/YY. Изменение в SORT_ASC или SORT_DESC везде, где необходимо:

array_multisort(array_column($array, 'status'), SORT_ASC, 
       array_map('strtotime', 
        str_replace('-', '/', 
         array_column($array, 'maildate'))), SORT_ASC, 
       array_column($array, 'mag'), SORT_ASC, 
       array_column($array, 'panel'), SORT_ASC, 
       $array); 

PHP> = 5.5.0, необходимое для array_column() или использовать PHP Implementation of array_column(). Или отметьте http://php.net/manual/en/function.array-multisort.php и используйте подход foreach() для создания массивов для использования в сортировке.

foreach($array as $row) { 
    $status[] = $row['status']; 
    $date[] = $row['maildate']; 
    $mag[] = $row['mag']; 
    $panel[] = $row['panel']; 
} 

Затем замените array_column() вызовы в роде с массивами ceated выше.

Примечание: На авось это исходит из базы данных, просто:

SELECT maildate, mag, panel, status FROM table_name ORDER BY status, maildate, mag, panel 

Использование функции базы данных для преобразования maildate в сортируемый формат, например, YYYY-mm-dd (примера: http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html)

+0

Он исходит из базы данных, но все элементы массива находятся не в одной строке в базе данных. Состояние изменяется с каждой строкой для данного элемента. Только первая строка имеет maildate, mag и панель. Я должен сделать второй запрос, чтобы получить последний статус. Но это была еще одна проблема. Спасибо –

+0

Хорошо, вы можете задать отдельный вопрос в структурах таблиц базы данных, и вы можете получить хороший способ запроса, который уже отсортирован. – AbraCadaver

+0

Дата почты штамп времени, так что я использовал это: 'code'array_multisort ( \t array_column ($ lblist, 'статус'), SORT_ASC, \t array_column ($ lblist, 'maildate'), SORT_ASC, \t array_column ($ lblist, 'mag'), SORT_ASC, \t array_column ($ lblist, 'panel'), SORT_ASC, \t $ lblist \t); , но это ничего не дает мне, фактически останавливает страницу от загрузки. –

Смежные вопросы