Convert a flat array to a nested array using materialized path

694 Views Asked by At

I have some categories that I need to convert to nested array (tree). I use materialized path to make a tree and I work in PHP. Here's a print_r of what I have:

Array
(
    [0] => Array
        (
            [_id] => mac
            [name] => Mac
            [path] => null
        )

    [1] => Array
        (
            [_id] => ipod
            [name] => iPod
            [path] => null
        )

    [2] => Array
        (
            [_id] => imac
            [name] => iMac
            [path] => ,mac,
        )

    [3] => Array
        (
            [_id] => imac2001
            [name] => iMac 2001
            [path] => ,mac,imac,
        )

    [4] => Array
        (
            [_id] => imac2002
            [name] => iMac 2002
            [path] => ,mac,imac,
        )

    [5] => Array
        (
            [_id] => imac2003
            [name] => iMac 2003
            [path] => ,mac,imac,
        )

)

I tried to make it but I get lost in the whole idea of recursive function.

UPDATE :

Here's what I would like to have ultimately :

Array
(
    [0] => Array
        (
            [_id] => mac
            [name] => Mac
            [path] => null
            [children] =>
                [0] => Array
                    (
                        [_id] => imac
                        [name] => iMac
                        [path] => ,mac,
                        [children] =>
                            [0] => Array
                                (
                                    [_id] => imac2001
                                    [name] => iMac 2001
                                    [path] => ,mac,imac,
                                )

                            [1] => Array
                                (
                                    [_id] => imac2002
                                    [name] => iMac 2002
                                    [path] => ,mac,imac,
                                )

                            [2] => Array
                                (
                                    [_id] => imac2003
                                    [name] => iMac 2003
                                    [path] => ,mac,imac,
                                )
                    )
        )

    [1] => Array
        (
            [_id] => ipod
            [name] => iPod
            [path] => null
        )
)

I'd like to show you what I already have coded but It's far from working so nothing good to see in my opinion.

1

There are 1 best solutions below

0
anousss On

I have found a solution. It's working for me so here it is:

<?php

$categories = Array
(
    [0] => Array
        (
            ["_id"] => "mac"
            ["name"] => "Mac"
            ["path"] => null
        )

    [1] => Array
        (
            ["_id"] => "ipod"
            ["name"] => "iPod"
            ["path"] => null
        )

    [2] => Array
        (
            ["_id"] => "imac"
            ["name"] => "iMac"
            ["path"] => ",mac,"
        )

    [3] => Array
        (
            ["_id"] => "imac2001"
            ["name"] => "iMac 2001"
            ["path"] => ",mac,imac,"
        )

    [4] => Array
        (
            ["_id"] => "imac2002"
            ["name"] => "iMac 2002"
            ["path"] => ",mac,imac,"
        )

    [5] => Array
        (
            ["_id"] => "imac2003"
            ["name"] => "iMac 2003"
            ["path"] => ",mac,imac,"
        )
)

$categoriesNested = sortTree($categories);

function sortTree(&$categories, $parent = null)
{
    $result = array();

    foreach($categories as $key => $cat)
    {
        if($parent == null)
        {
            $temp = $cat;
            unset($categories[$key]);
            $temp["children"] = $this->sortTree($categories, $cat);
            $result[] = $temp;
        }
        else
        {
            $tempPath = array_values(array_filter(explode(',', $cat["path"])));
            $directParent = array_pop($tempPath);
            if ($parent["_id"] == $directParent)
            {
                $temp = $cat;
                unset($categories[$key]);
                $temp["children"] = $this->sortTree($categories, $cat);
                $result[] = $temp;
            }
        }
    }

    if (empty($result))
        return null;
    else
        return $result;
}