Determine all descendants for this root.

  • There is a table of categories with a perfectly standard and well-known structure: йidйparent_idйnameй...й Once upon a time, a very good function has been found on the network to form a tree of categories with any level of investment:

    public function mapTree($dataset)
        $tree = [];
    foreach ($dataset as $id=>&$node) {
        if (!$node['parent_id']) {
            $tree[$id] = &$node;
        } else {
            $dataset[$node['parent_id']]['childs'][$id] = &$node;
    return $tree;


    The challenge is: a structured tree must be formed from the OBD in such a way as:

    • Category 1 (Head)

      • Title 1
      • Uniform mass of all category 1 descendants, taking into account all investments
    • Category 2 (Head)
      • Title 2
      • Uniform mass of all category 2 descendants, taking into account all investments
    • ...and so forth.

    The difficulty is that the database, for example, Categoria 1 (which origins from parent_id=0) may have as many descendants, and these descendants, in turn, their descendants, etc. - shorterly speaking, an ancient structure with unknown levels of investment. Thus, it is necessary that, as a result, there should be a mass of the above structure at the exit.

    Question: Is there any way to modify the function I have given, or how can it be implemented?

    P.S.: I'd like to deal with this topic on some simple examples to make sure it's gone, and if you don't have a job, you could not show, on the other hand, a list of all ancestors for the current category (this might be useful for the same newcomers as me - for example, in the formation of bread crumbs on the website).

  • <?php
    $input=array(  // Исходный массив (как в базе)
                  array("id"=>2, "parent_id"=>1, "name"=>"Category 1"),
                  array("id"=>4, "parent_id"=>2, "name"=>"Category 1.1"),
                  array("id"=>8, "parent_id"=>4, "name"=>"Category 1.1.1"),
                  array("id"=>5, "parent_id"=>2, "name"=>"Category 1.2"),
                  array("id"=>3, "parent_id"=>1, "name"=>"Category 2"),
                  array("id"=>6, "parent_id"=>3, "name"=>"Category 2.1"),
                  array("id"=>7, "parent_id"=>3, "name"=>"Category 2.2"),
                  array("id"=>9, "parent_id"=>3, "name"=>"Category 2.3"),
                  array("id"=>1, "parent_id"=>0, "name"=>"root element 1"),
                  array("id"=>10, "parent_id"=>0, "name"=>"root element 2")
    foreach ($input as &$node) { // Строим предварительный массив с индексами по parent_id
     if(!$node['parent_id']) { // Это корневой элемент - перенести только имя
      } else { // Добавить элемент в массив с ключом parent_id
    var_dump($result); // Печать предварительного массива
    foreach ($result as $k=>&$node) { // Для всех корневых элементов строим ветви
     if(array_key_exists('name',$node)) BuildTree($result,$node);
    var_dump($result); // Печать дерева
    function BuildTree(&$result,&$root) // Функция перестройки ветви
    { // Параметры - весь массив и текущая ветвь
     foreach ($root as $k=>&$node) {
       if(!is_array($node)) continue;
       if(isset($result[$node['id']])) {          // Если есть элементы с parent_id=текущий id
         BuildTree($result,$result[$node['id']]); // Строим дерево для вложенных элементов
         $root[$k][]=$result[$node['id']];        // переносим вложенную ветвь из начального массива на ее место
         unset($result[$node['id']]);             // Удаляем ветвь с изначального места

    Algorithm is their two stages. The first basement is moved to work. However, all non-indigenous elements are placed in parent_id keys, so knowing the id branches can be found instantly in this body of all of her immediate children. All that remains at the second stage is to move children into invested masses to their parents. This part of the passive, if the current test piece has children, their records are transferred from indexed positions in the total mass to their place in the parent(s) element.

    And in order to find all the parent elements, we need to build a id-element keys, and then we take a parent-id cell into that mass, it's a parent, if he has the same parent_id, then we go through it and get Grandpa, etc.

Log in to reply

Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2