1

I'm having some problems building an hierarchistic array structure - I have almost got it done, but there's something unexplained that makes my array look weird which I hoped you could help me with.

The tree structure is:

root
|data
|-children
|--data
|--children
|---data
|---children

Any child can have any number of children and each child can have any number of parents.

I have a function that builds the tree:

private function build_tree($rows,$parent) {
    $i = 0;
    $response -> result = array();
    $result = array();
    $leaf = false;

    foreach($rows as $row) {
        if($row['parent_id'] == $parent) {
            $leaf = is_null($row['treeDef']) ? false : true;
            $workingSet = array_merge($result,array(                
                'id' => (int)$i, 
                'parent_id' => (int)$row['parent_id'], 
                'child_id' => (int)$row['id'], 
                'name' => (string)$row['resourceName'], 
                'updated' => strtotime($row['updated']), 
                'purchasedUnit' => (string)$row['purchasingUnit'], 
                'purchasedCost' => (double)$row['purchasingCosts'], 
                'purchasedDiscount' => (double)$row['discount'], 
                'estimateUnit' => (string)$row['estimatingUnit'], 
                'profitAddOn' => (string)$row['profitAddOn'], 
                'landedCost' => (double)$row['landedCost'], 
                'unitCorrelation' => (double)$row['unitCorrelation'], 
                'leadTime' => (string)$row['leadTime'], 
                'ResourceClassShortname' => (string)$row['ResourceClassShortname'], 
                'supplierName' => (string)$row['nameSupplier'],
                'iconCls' => (string)$row['typeIcon'],
                'leaf' => $leaf
            ));
            $hasChildren = $this->Resource_model->has_children($rows,$row['id']);
            if ($hasChildren->check) {
                if (!$leaf) {
                    for($j=0; $j <= ($hasChildren -> rows); $j++) {
                        $parentArray = $workingSet;
                        $childArray = $this -> Resource_model -> build_tree($rows,$row['id']);
                        $workingSet = array_merge($parentArray,array('children' => $childArray -> result));
                    }
                } 
            }
            $result[$i] = $workingSet;
            $i++;
        }
    }

    $response -> result = $result;
    $response -> rows = $i; 
    return $response;
}

Which produces this JSON:

PrintScreen

Big picture

Every item that has 2 children (or more? - no test values) gets the first item like it should be, but the second item contains the first item as well - duplicating all the results.

Any help appreciated.

2 Answers 2

1

Instead of array_merge use array_push - this will add the children subarray instead of trying merging it with the one already existing...

It's in this part of code (already edited):

        $hasChildren = $this->Resource_model->has_children($rows,$row['id']);
        if ($hasChildren->check) {
            if (!$leaf) {
                for($j=0; $j <= ($hasChildren->rows); $j++) {
                    $parentArray = $workingSet;
                    $childArray = $this->Resource_model->build_tree($rows,$row['id']);
                    $workingSet = array_push($parentArray,array('children' => $childArray->result));
                }
            } 
        }
Sign up to request clarification or add additional context in comments.

3 Comments

I have some problems implementing this: A PHP Error was encountered Severity: Warning Message: array_push() expects parameter 1 to be array, integer given
Adding print_r($parentArray); and print_r($childArray); both prints array structures.
Then how it is possible that the error says the $parentArray is integer? Try to var_dump($parrentArray); for all loops and recurses... Somewhere there must be a point when $parentArray becomes an integer...
0

Made it work, here's the final code:

private function build_tree($rows,$parent) {
    $i = 0;
    $response -> result = array();
    $result = array();
    $leaf = false;
    $newArray = array();

    foreach($rows as $row) {
        if($row['parent_id'] == $parent) {
            $leaf = is_null($row['treeDef']) ? false : true;
            $newArray = array(              
                'id' => (int)$i, 
                'parent_id' => (int)$row['parent_id'], 
                'child_id' => (int)$row['id'], 
                'name' => (string)$row['resourceName'], 
                'updated' => strtotime($row['updated']), 
                'purchasedUnit' => (string)$row['purchasingUnit'], 
                'purchasedCost' => (double)$row['purchasingCosts'], 
                'purchasedDiscount' => (double)$row['discount'], 
                'estimateUnit' => (string)$row['estimatingUnit'], 
                'profitAddOn' => (string)$row['profitAddOn'], 
                'landedCost' => (double)$row['landedCost'], 
                'unitCorrelation' => (double)$row['unitCorrelation'], 
                'leadTime' => (string)$row['leadTime'], 
                'ResourceClassShortname' => (string)$row['ResourceClassShortname'], 
                'supplierName' => (string)$row['nameSupplier'],
                'iconCls' => (string)$row['typeIcon'],
                'leaf' => $leaf
            );

            $hasChildren = $this -> Resource_model -> has_children($rows,$row['id']);
            if ($hasChildren->check) {
                for($j=0; $j <= ($hasChildren -> rows); $j++) {
                    $childArray = $this -> Resource_model -> build_tree($rows,$row['id']);
                    $newArray = array_merge($newArray, array('children' => $childArray -> result));
                }
            }
            $result[$i] = $newArray;
            $i++;
        }
    }

    $response -> result = $result;
    $response -> rows = $i; 
    return $response;
}

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.