0

I'm trying to fill data json for treemaker.js from database data; the result set looks like this:

[
    ['id' => 1, 'root' => 1, 'parent_id' => 0],
    ['id' => 2, 'root' => 1, 'parent_id' => 1],
    ['id' => 3, 'root' => 1, 'parent_id' => 2],
    ['id' => 4, 'root' => 1, 'parent_id' => 2],
    ['id' => 5, 'root' => 1, 'parent_id' => 3],
    ['id' => 6, 'root' => 1, 'parent_id' => 3],
    ['id' => 7, 'root' => 1, 'parent_id' => 4],
    ['id' => 8, 'root' => 1, 'parent_id' => 4],
    ['id' => 9, 'root' => 1, 'parent_id' => 4],
]

I expected the json output should be like this:

{ 
    '1': {
        '2': {
            '3': {
                '5': '',
                '6': '',
            },
            '4': {
                '7': '',
                '8': '',
                '9': '',
            },
        },
    },
}

I already tried :

function buildTree(array $elements, $parentId = 0) {
    $branch = [];
    $new = [];
    foreach ($elements as $element) {
        if ($element['parent_id'] == $parentId) {
            $children = $this->buildTree($elements, $element['id']);
            if ($children) {
                $element[$element['id']] = $children;
            } else {
                $element[$element['id']] = '';
            }
            unset($element["id"]);
            unset($element["root"]);
            unset($element["parent_id"]);
            $branch[] = $element;
        }
    }
    return $branch;
}

public function test($id)
{
    $data = $this->Data_model->getDataByRoot($id)->result_array();
    $tree = $this->buildTree($data);
    echo "<pre>";
    print_r( json_encode($tree, JSON_PRETTY_PRINT|JSON_FORCE_OBJECT));
}

I got the reference from PHP hierarchical array - Parents and childs, but the result is like this.

2 Answers 2

0

Here is my solution:

function buildTree(array &$elements, $parentId = 0)
{
    $branch = [];

    foreach ($elements as $element) {
        if ($element['parent_id'] == $parentId) {
            $id = $element['id'];
            $children = buildTree($elements, $id);

            if ($children) {
                $branch[$id] = $children;
            } else {
                $branch[$id] = '';
            }
        }
    }
    return $branch;
}
Sign up to request clarification or add additional context in comments.

1 Comment

This answer is missing its educational explanation.
0

While iterating and recursing when a matching parent_id is encountered, push the child data into an element which is keyed by the current row's id. If there are no children for the row, fall back to an empty string with the shorthand ternary operator (aka "Elvis operator").

Code: (Demo)

function buildTree(array $rows, int $parentId = 0): array {
    $new = [];
    foreach ($rows as $row) {
        if ($row['parent_id'] == $parentId) {
            $new[$row['id']] = buildTree($rows, $row['id']) ?: '';
        }
    }
    return $new;
}

$resultSet = [
    ['id' => 1, 'parent_id' => 0],
    ['id' => 2, 'parent_id' => 1],
    ['id' => 3, 'parent_id' => 2],
    ['id' => 4, 'parent_id' => 2],
    ['id' => 5, 'parent_id' => 3],
    ['id' => 6, 'parent_id' => 3],
    ['id' => 7, 'parent_id' => 4],
    ['id' => 8, 'parent_id' => 4],
    ['id' => 9, 'parent_id' => 4],
];

var_export(
    buildTree($resultSet)
);

My advice largely resembles the advice given here.

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.