Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert class array

Tags:

php

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.

like image 437
phame Avatar asked Dec 28 '25 22:12

phame


1 Answers

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.

like image 157
steffen Avatar answered Dec 30 '25 15:12

steffen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!