Как массив элементов разделить на родительские и дочерние?

Задачу эту придется решить на PHP, но в самом вопросе я хотел бы помощи гуру в том числе и в выборе правильного алгоритма, без привязки к языку. Для удобства пример в json.

Есть некий массив элементов - меню например:
[
  {
    "id": 1,
    "parent": 0
  },
  {
    "id": 2,
    "parent": 0
  },
  {
    "id": 3,
    "parent": 1
  },
]


Каждый элемент содержит уникальный id, какие-то ещё данные (ссылка, название и т.д.) и id родительского элемента.
Код в примере изображает меню из двух пунктов на первом уровне и 1 на втором. Это может быть к примеру выпадающее меню.

Условная разметка для этого меню
<ul class="parent">
        <li> id1
            <ul class="child">
                <li>id3</li>
            </ul>
        </li>
        <li>id2</li>
    </ul>


Соответственно данные нужно либо подготовить перед передачей в шаблон, либо как-то обработать в самом шаблоне.
Мне видится хорошим вариантом превратить массив в такой:
[
  {
    "id": 1,
    "childs": [
      {
        "id": 3
      }
    ]
  },
  {
    "id": 2
  }
]


Тогда вывести будет просто:
элемент > если есть дочерние - создаем обертку для них > дочерний элемент.... и т.д.

Как правильнее преобразовать массив 1 в массив 2?

Я пробовал такой вариант как обход элементов и создание нового массива:
Например, если элемент родительский, то создаем $arrNew[%id_родительского%]. Если элемент дочерний, то соответственно $arrNew[%id_родительского%]['childs'][%id_дочернего%].

Может быть есть более правильное решение?
  • Вопрос задан
  • 1029 просмотров
Решения вопроса 1
hahenty
@hahenty
('•')
Поэлементный обход — это решение "в лоб". С ним будут проблемы при неупорядоченности в массиве, когда дочерние элементы будут встречены раньше своих родительских.

var list = [/*исходный массив*/];
var menu = list
.map( function(a) {
  //сначала строим список дочерних
  a.children = list.filter( function(b) {
    return b.parent === a.id;
  });
  return a;
})
.filter( function(a) {
  //потом убираем некорневые элементы
  return a.parent === 0;
})

Элементы, которые приписаны к несуществующим родительским, будут отфильтрованы.
"сто раз так делал"
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы