Да, да, я знаю, вот несколько вопросов о сортировке массивов, но мне нужно еще одно конкретное объяснение.
У меня есть таблица БД для хранения многоуровневого меню с продуктами.
Как: itemId, parentId, itemtitle, …
Я использую эту таблицу для построения меню на веб-странице, используя рекурсивную функцию, и я хочу использовать эту DB-таблицу для получения данных для внутренней HTML-формы, для списка опций.
Несортированные данные из БД мне нужно правильно отсортировать и поместить в массив json.
Половина работы, которую я сделал с этим:
//empty arrays for sorting purposes
$ids = array();
$parents = array();
// iterate, $items - unsorted array from DB
foreach ($items as $key => $row) {
$ids[$key] = $row['itemId'];
$parents[$key] = $row['parentId'];
}
// sorting
array_multisort($ids, SORT_ASC, $parents, SORT_ASC, $items);
//now $items partly sorted
РИСУНОК 1
Итак, список $ items выглядит так:
(itemId — parentId — itemTitle)
1 — 0 — *** А
2 — 0 — *** B
3 — 0 — *** C
4 — 0 — *** D
6 — 1 — *** E
7 — 1 — *** F
8 — 1 — *** G
9 — 2 — *** Н
10 — 2 — *** я
11 — 2 — *** Дж
12 — 2 — *** К
13 — 2 — *** л
14 — 3 — *** М
15 — 3 — *** Н
16 — 3 — *** О
17 — 4 — *** П
18 — 4 — *** Q
РИС.2
Я нуждаюсь:
1 — 0 — *** А
6 — 1 — *** E
7 — 1 — *** F
8 — 1 — *** G
2 — 0 — *** B
9 — 2 — *** Н
10 — 2 — *** я
11 — 2 — *** Дж
12 — 2 — *** К
13 — 2 — *** л
3 — 0 — *** C
14 — 3 — *** М
15 — 3 — *** Н
16 — 3 — *** О
4 — 0 — *** D
17 — 4 — *** П
18 — 4 — *** Q
Так что это мое мнение. Только двухуровневое меню:
//get all categories, primary sorted by MySQL
$items = $cataloAR->query("SELECT itemId, parentId,itemTitle FROM `catalog` ORDER BY parentId, itemId");
//pre-sort by - itemId, parentId
$ids = array();//array for id`s
$parents = array();//array for parents
// get columns list
foreach ($items as $key => $row) {
$ids[$key] = $row['itemId'];
$parents[$key] = $row['parentId'];
}
// sort ascending by id, ascending by parent
array_multisort($ids, SORT_ASC, $parents, SORT_ASC, $items);
//make emptyarray for sorteddata, like - $entryList['itemId']['itemTitle']
$entryList = array();//empty array
$len = count($items); //count elements for proceeding
$currentEntry = 0; //current element number,start from 0-element
//iterate
//while reaching last element in list
while($currentEntry < $len){
//if current element is empty => go to next element
if (!isset($items[$currentEntry])) {
$currentEntry++;
}
//get current element from $items
//put it to $entryList
$entryList[] = $items[$currentEntry];
// get current id
$currentId = $items[$currentEntry]['itemId'];
//remove element from $items, because we just put it to the sorted list
unset($items[$currentEntry]);
//search in $items entries with patternId = $items['itemId']
//put to sorted list
//remove element
foreach ($items as $key => $value) {
if($value['parentId'] == $currentId){
$entryList[] = $value;
unset($items[$key]);
}
if (!isset($value)){
continue;
}
}
//increase counter
$currentEntry++;
}
//purge sorted list from empty elements $entryList
$sortedList = array_filter($entryList);
//Enjoy it!
return $sortedList;
Я сделал некоторые предположения о вашем массиве и создал его с помощью приведенного ниже кода. Мне удалось воспроизвести желаемый результат, создав два новых массива ($ root и $ menu), а затем перебрав каждый из них, чтобы построить меню. Это было непросто, и лучшим ответом было бы на самом деле построить этот массив с самого начала, но если это невозможно, этот код должен привести вас туда, где вам нужно:
$items[] = array('itemId' => 1,'parentId' => 0,'itemTitle' => '***A');
$items[] = array('itemId' => 2,'parentId' => 0,'itemTitle' => '***B');
$items[] = array('itemId' => 3,'parentId' => 0,'itemTitle' => '***C');
$items[] = array('itemId' => 4,'parentId' => 0,'itemTitle' => '***D');
$items[] = array('itemId' => 6,'parentId' => 1,'itemTitle' => '***E');
$items[] = array('itemId' => 7,'parentId' => 1,'itemTitle' => '***F');
$items[] = array('itemId' => 8,'parentId' => 1,'itemTitle' => '***G');
$items[] = array('itemId' => 9,'parentId' => 2,'itemTitle' => '***H');
$items[] = array('itemId' => 10,'parentId' => 2,'itemTitle' => '***I');
$items[] = array('itemId' => 11,'parentId' => 2,'itemTitle' => '***J');
$items[] = array('itemId' => 12,'parentId' => 2,'itemTitle' => '***K');
$items[] = array('itemId' => 13,'parentId' => 2,'itemTitle' => '***L');
$items[] = array('itemId' => 14,'parentId' => 3,'itemTitle' => '***M');
$items[] = array('itemId' => 15,'parentId' => 3,'itemTitle' => '***N');
$items[] = array('itemId' => 16,'parentId' => 3,'itemTitle' => '***O');
$items[] = array('itemId' => 17,'parentId' => 4,'itemTitle' => '***P');
$items[] = array('itemId' => 18,'parentId' => 4,'itemTitle' => '***Q');
foreach ($items as $itemArray) {
$parent = $itemArray['parentId'];
$item = $itemArray['itemId'];
$title = $itemArray['itemTitle'];
if ($parent == 0) {
// this is a root item
$root[$item] = $title;
} else {
// this is a submenu item
$menu[$parent][$item] = $title;
}
}
foreach ($root as $key => $value) {
// this is a root item, which is always 0.
echo "$key, 0, $value <br/>";
foreach ($menu as $parent => $item) {
if ($parent == $key) {
foreach ($item as $itemId => $title) {
// output the submenu items under the root
echo "$itemId, $parent, $title <br />";
}
}
}
}
Других решений пока нет …