Umair A.
Umair A.

Reputation: 6873

PHP Adjacency List to Nested Array

I am trying to convert following table data into nested array using PHP. I am almost done but stuck at one point.

id  name                    parent
1   Apparel                                                                   
2   Appliances                                                                
46  Apparel                 1                                                 
47  Child Apparel           46                                                
49  Child Apparel 2         47        

Using this code

$cats = array(); // from database

$refs = array();
$rcats = array();

foreach ($cats as $cat) {
    $thisref = &$refs[$cat['id']];

    $thisref['id'] = $cat['id'];
    $thisref['name'] = $cat['name'];
    $thisref['leaf'] = "true";

    if (!$cat['parent']) {
        $rcats[$cat['id']] = &$thisref;
    } else {
        unset($refs[$cat['parent']]['leaf']);
        $refs[$cat['parent']]['items'][$cat['id']] = &$thisref;
    }
}          

print_r(json_encode($rcats));                             

This results into following JSON.

{
    "1": {
        "id": "1",
        "name": "Apparel",
        "items": {
            "46": {
                "id": "46",
                "name": "Apparel",
                "items": {
                    "47": {
                        "id": "47",
                        "name": "Child Apparel",
                        "items": {
                            "49": {
                                "id": "49",
                                "name": "Child Apparel 2",
                                "leaf": "true"
                            }
                        }
                    }
                }
            }
        }
    },
    "2": {
        "id": "2",
        "name": "Appliances",
        "leaf": "true"
    }
}

Where as I want the JSON like

[
    {
        "id": "1",
        "name": "Apparel",
        "items": [
            {
                "id": "46",
                "name": "Apparel",
                "items": [
                    {
                        "id": "47",
                        "name": "Child Apparel",
                        "items": [
                            {
                                "id": "49",
                                "name": "Child Apparel 2",
                                "leaf": "true"
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        "id": "2",
        "name": "Appliances",
        "leaf": "true"
    }
]

Upvotes: 0

Views: 1261

Answers (2)

W Kristianto
W Kristianto

Reputation: 9303

Am i wrong? :p

$cats      = array(); // From Database, but i use this
$cats      = array(
    array(
        'id'        => 1,
        'name'      => 'Jakarta',
        'parent'    => NULL
    ),
    array(
        'id'        => 2,
        'name'      => 'Bandung',
        'parent'    => 1
    ),
    array(
        'id'        => 3,
        'name'      => 'Surabaya',
        'parent'    => 1
    ),
    array(
        'id'        => 4,
        'name'      => 'Bali',
        'parent'    => NULL
    ),
    array(
        'id'        => 5,
        'name'      => 'Batam',
        'parent'    => NULL
    ),
);
$refs        = array();
$rcats   = array();

foreach ($cats as $cat) {
    $thisref            = &$refs[$cat['id']];
    $thisref['id']  = $cat['id'];
    $thisref['name']    = $cat['name'];
    $thisref['leaf']    = "true";

    if (!$cat['parent']) {
        $rcats[] = &$thisref;
    } 
    else {
        unset($refs[$cat['parent']]['leaf']);
        $refs[$cat['parent']]['items'][] = &$thisref;
    }
}      

/*
// IF YOU NEED CHANGE TO OBJECT

$rcats = (object)$rcats;
if(isset($rcats->items)){
    $rcats->items = (object)$rcats->items;
}
*/

header('Content-type: application/json');
print_r(json_encode($rcats));

Upvotes: 1

Andreas Wong
Andreas Wong

Reputation: 60526

Here I'm assuming you are storing your final results in $refs

print_r(json_encode(array_values($rcats)));

If you want to take out all the indexes, in your for loop, do [] instead of the id:

if (!$cat['parent']) {
    $rcats[] = &$thisref;
} else {
    unset($refs[$cat['parent']]['leaf']);
    $refs[$cat['parent']]['items'][] = &$thisref;
}

A quick example I throw:

<?php

$a = array('1' => array('a' => 3), '2' => array('b' => 4));
echo json_encode($a) . "\n";
echo json_encode(array_values($a)) . "\n";

Outputs:

{"1":{"a":3},"2":{"b":4}}
[{"a":3},{"b":4}]

Upvotes: 0

Related Questions