Построение древа без родительского id

была поставлена задача распарсить эксельку для заполнения бд. Для начала необходимо построить дерево. Имею коллекцию типа:

   0 => array:4 [▼
      "level1" => "Автомобиль"
      "level2" => "Легковые"
      "level3" => "Отечественные"
      "level4" => null
    ]
    1 => array:4 [▼
      "level1" => "Автомобиль"
      "level2" => "Грузовые"
      "level3" => "Тяжелее 3 тонн"
      "level4" => "Отечественные"
    ]
    2 => array:4 [▼
      "level1" => "Автомобиль"
      "level2" => "Грузовые"
      "level3" => "Легче 3 тонн"
      "level4" => "Иностранные"
    ]
    3 => array:4 [▼
      "level1" => "Мотоцикл"
      "level2" => "Классический"
      "level3" => "Отечественные"
      "level4" => null
    ]
    4 => array:4 [▼
      "level1" => "Мотоцикл"
      "level2" => "Спортивный"
      "level3" => "Иностранные"
      "level4" => null
    ]

Я не очень понимаю как построить КАЧЕСТВЕННО рекурсивно дерево не имея родительского id. Прошу подсказать правильный алгоритм для превращении коллекции в дерево.


Ответы (1 шт):

Автор решения: Егор Банин

Просто постройте дерево в уме (или на листке бумаги) и запишите свои действия. Немного поразмышляйте над результатом и упростите его.

Вот как это получилось у меня:

  1. Для каждого элемента из списка. Обходим свойства элемента по порядку.
  2. Для каждого свойства выполняем следующее: Если значения свойства нет на соответствующем уровне, то добавляем его.

Всё просто. Осталось добавить обработку случаев, когда по какой-то причине данные некорректны. Как видите никакой рекурсии не потребовалось, а дерево получилось довольно качественное.

Осталось сохранить дерево в бд. Если вы говорите о родительском id, то вероятно храните дерево как строки id, parentId, ... (обратите внимание, что это не единственный способ). Тогда обходите дерево (можно рекурсивно) и на каждом шаге инсертите значение в бд, получая id вставленной записи.

Если дерево как структура на этом этапе вам не требуется, то логичнее сразу инсертить в бд при обходе вашей коллекции. Алгоритм не поменяется.

  1. Для каждого элемента из списка. Обходим свойства элемента по порядку.
  2. Для каждого свойства выполняем следующее: Если значения свойства нет на соответствующем уровне, то добавляем его и инсертим в бд. При вставке, получаем id, который используем для дочерних элементов как родительский.

Попробуйте реализовать. Если будут затруднения, пишите, помогу.

→ Ссылка