3

I need to convert this class array

$categoriesArray = array();
//                                    ID, PARENT_ID, NAME
$categoriesArray[] = Category::create(1,   0,       "Category A");
$categoriesArray[] = Category::create(2,   0,       "Category B");
$categoriesArray[] = Category::create(3,   0,       "Category C");
$categoriesArray[] = Category::create(4,   2,       "Sub-cat F");
$categoriesArray[] = Category::create(5,   2,       "Sub-Cat G");
$categoriesArray[] = Category::create(6,   3,       "Sub-Cat H");

Into this:

$x = new CategoryTree("Main");
$x->add_sub_cat(new CategoryTree($categoriesArray[0]->name));                           //Category A
$x->add_sub_cat(new CategoryTree($categoriesArray[1]->name));                           //Category B
$x->add_sub_cat(new CategoryTree($categoriesArray[2]->name));                           //Category C
$x->subCats[1]->add_sub_cat(new CategoryTree($categoriesArray[3]->name));               //Sub-Cat F
$x->subCats[1]->add_sub_cat(new CategoryTree($categoriesArray[4]->name));               //Sub-Cat G
$x->subCats[2]->add_sub_cat(new CategoryTree($categoriesArray[5]->name));               //Sub-Cat H

subCats can be unlimited hierarchy, so I don't know how many levels there will be. I understand, that recursion is required, but I have no idea how to convert it to that.

I need this because I am doing category tree and I'am trying to make a form, to add categories (by entering name and selecting parent).

If there is any way to add category to something like my second example, it would help me alot.

1 Answer 1

1

Apparently you have a class like this (I leave out private member declarations here):

class Category {
        static function create($id, $parentId, $name) {
                $category = new Category();
                $category->id = $id;
                $category->parentId = $parentId;
                $category->name = $name;
                return $category;
        }
        function add_sub_cat($cat) {
                $cat->parentId = $this;
        }
}

That works with your posted code:

$categoriesArray = [];
$categoriesArray[] = Category::create(1,   0,       "Category A");
$categoriesArray[] = Category::create(2,   0,       "Category B");
$categoriesArray[] = Category::create(3,   0,       "Category C");
$categoriesArray[] = Category::create(4,   2,       "Sub-cat F");
$categoriesArray[] = Category::create(5,   2,       "Sub-Cat G");
$categoriesArray[] = Category::create(6,   3,       "Sub-Cat H");

And you seem to have a Category Tree class which seems to be similar to this:

class CategoryTree {
    function __construct($name) {
        $this->name = $name;
    }
    function add_sub_cat($catTree) {
        $this->subCats[] = $catTree;
    }
}

Again your posted code:

$x = new CategoryTree("Main");
$x->add_sub_cat(new CategoryTree($categoriesArray[0]->name));                           //Category A
$x->add_sub_cat(new CategoryTree($categoriesArray[1]->name));                           //Category B
$x->add_sub_cat(new CategoryTree($categoriesArray[2]->name));                           //Category C
$x->subCats[1]->add_sub_cat(new CategoryTree($categoriesArray[3]->name));               //Sub-Cat F
$x->subCats[1]->add_sub_cat(new CategoryTree($categoriesArray[4]->name));               //Sub-Cat G
$x->subCats[2]->add_sub_cat(new CategoryTree($categoriesArray[5]->name));               //Sub-Cat H

You get this:

object(CategoryTree)#7 (2) {
  ["name"]=>
  string(4) "Main"
  ["subCats"]=>
  array(3) {
    [0]=>
    object(CategoryTree)#8 (1) {
      ["name"]=>
      string(10) "Category A"
    }
    [1]=>
    object(CategoryTree)#9 (2) {
      ["name"]=>
      string(10) "Category B"
      ["subCats"]=>
      array(2) {
        [0]=>
        object(CategoryTree)#11 (1) {
          ["name"]=>
          string(9) "Sub-cat F"
        }
        [1]=>
        object(CategoryTree)#12 (1) {
          ["name"]=>
          string(9) "Sub-Cat G"
        }
      }
    }
    [2]=>
    object(CategoryTree)#10 (2) {
      ["name"]=>
      string(10) "Category C"
      ["subCats"]=>
      array(1) {
        [0]=>
        object(CategoryTree)#13 (1) {
          ["name"]=>
          string(9) "Sub-Cat H"
        }
      }
    }
  }
}

The latter code can be replaced by this code that does it dynamically:

// You need to make sure the array defines all parent categories first before
// sub categories can refer to them. This might already be the case, but we
// make that sure by sorting by parentId.
usort($categoriesArray, function($c1, $c2) { return $c1->parentId-$c2->parentId; });
// The trick is to build up a (flat) registry where you can simply add children
$x = new CategoryTree("Main");
$registry = [0 => $x]; // One entry: Main (parentId = 0)
foreach ($categoriesArray as $c) {
    $catTree = new CategoryTree($c->name);
    $registry[$c->id] = $catTree;
    $registry[$c->parentId]->add_sub_cat($catTree);
}

BTW: You don't have a class array, categoriesArray is a simple (object) array.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.