Жаль, что вы не объясните, для чего это будет использоваться, но это общая проблема с вопросами переполнения стека. Суть проблемы часто отсутствует, поэтому она становится абстрактным упражнением.
Например, я не вижу смысла в перестановке массива таким специфическим способом. Я думаю, что полученный массив мог бы использовать ключи массива более эффективно. Там также много повторений информации.
Но это то, что мы получили, поэтому без дальнейших жалоб с моей стороны, вот код, который я придумал:
function rearrangeItems($flatItems, $groups)
{
$groupedItems = [];
$groupName = array_shift($groups);
$groupValues = array_unique(array_column($flatItems, $groupName));
foreach ($groupValues as $groupValue) {
$children = [];
foreach ($flatItems as $flatItem) {
if ($flatItem[$groupName] == $groupValue) {
$children[] = $flatItem;
}
}
if (count($groups) > 0) {
$children = rearrange($children, $groups);
$groupKey = "children";
}
else {
$groupKey = "data";
}
$groupedItems[] = ["fieldName" => $groupName,
"value" => $groupValue,
$groupKey => $children];
}
return $groupedItems;
}
Да, это все, что нужно. Это приводит к тому же результату.
Эта функция рекурсивная , она выполняет один уровень группировки и затем передает результат на следующий уровень, пока не останется больше уровней. Комплексный бит:
array_unique(array_column($flatItems, $groupName))
Возвращает все различные значения на текущем уровне группировки.
Это не самый эффективный алгоритм, но он понятен. Если бы я попытался сделать его более эффективным, читаемость, вероятно, пострадала бы, и это никогда не было хорошо.