Jump to content
Sign in to follow this  
frontEndCoder

Generate JSON structure from array of items

Recommended Posts

I have this array of items in my php file.

 

$items = array(
    array("id" => 100,"categorypath" => "level1/powders", "product" => "Mens powder"),
    array("id" => 200,"categorypath" => "level1/oils/sunflower", "product" => "XYZ oil"),
    array("id" => 300,"categorypath" => "level1/eatable/vegetables", "product" => "carrot"),
    array("id" => 400,"categorypath" => "level1/oils/sunflower", "product" => "ABC oil"),
    array("id" => 500,"categorypath" => "level1/eatable/fruits", "product" => "mango"),
    array("id" => 600,"categorypath" => "level1/eatable/vegetables", "product" => "spinach"),
    array("id" => 700,"categorypath" => "level2/baby items/toys", "product" => "puzzle block"),
    array("id" => 800,"categorypath" => "level2/baby items/toys", "product" => "trucks and cars"),
    array("id" => 900,"categorypath" => "level2/baby items/clothes", "product" => "shirts"),
    array("id" => 1000,"categorypath" => "level1/powders", "product" => "Womens powder"),
    array("id" => 1100,"categorypath" => "level1/oils/groundnut", "product" => "GN oil"), 
);

Using the above array I am trying to generate a JSON file that will have the following structure:

 

{
  "category":[
    {
      "categoryName":"level1",
      "category":[
        {
          "categoryName":"powders",
          "products":[
            {
              "id":"100",
              "path":"level1/powders",
              "prodname":"Mens powder"
            },
            {
              "id":"1000",
              "path":"level1/powders",
              "prodname":"Womens powder"
            }
          ]
        },
        {
          "categoryName":"oils",
          "category":[
            {
              "categoryName":"sunflower",
              "products":[
                  {
                    "id":"200",
                    "path":"level1/oils/sunflower",
                    "prodname":"XYZ oil"
                  },
                  {
                    "id":"400",
                    "path":"level1/oils/sunflower",
                    "prodname":"ABC oil"
                  }

              ]
            },
            {
              "categoryName":"groundnut",
              "products":[
                  {
                    "id":"1100",
                    "path":"level1/oils/groundnut",
                    "prodname":"GN oil"
                  }
              ]
            }
          ]
        },
        {
          "categoryName":"eatable",
          "category":[
            {
              "categoryName":"vegetables",
              "products":[
                {
                  "id":"300",
                  "path":"level1/eatable/vegetables",
                  "prodname":"carrot"
                },
                {
                  "id":"600",
                  "path":"level1/eatable/vegetables",
                  "prodname":"spinach"
                }
              ]
           },
           {
              "categoryName":"fruits",
              "products":[
                {
                  "id":"500",
                  "path":"level1/eatable/fruits",
                  "prodname":"mango"
                }
                  
              ]
            }
            
          ]
        }
        
    },
    {
      "categoryName":"level2",
      "category":[
        {
          "categoryName":"baby items",
          "category":[
            {
              "categoryName":"toys",
              "products":[
                {
                  "id":"700",
                  "path":"level2/baby items/toys",
                  "prodname":"puzzle blocks"
                },
                {
                  "id":"800",
                  "path":"level2/baby items/toys",
                  "prodname":"trucks and cars"
                }
              ]
            },
            {
              "categoryName":"clothes",
              "products":[
                {
                  "id":"900",
                  "path":"level2/baby items/clothes",
                  "prodname":"shirts"
                }
              ]
            }
          ]
        }

      ]
    }

Not being an expert in php, I have somehow managed to reach thus far in my code, but can not quite arrive at the correct logic. Having trouble with handling associative arrays and objects in php. (Javascripting is much easier I feel) So far I have managed to fix all the errors/warning in my code.

Here is my full php code:

 

$items = array(
    array("id" => 100,"categorypath" => "level1/powders", "product" => "Mens powder"),
    array("id" => 200,"categorypath" => "level1/oils/sunflower", "product" => "XYZ oil"),
    array("id" => 300,"categorypath" => "level1/eatable/vegetables", "product" => "carrot"),
    array("id" => 400,"categorypath" => "level1/oils/sunflower", "product" => "ABC oil"),
    array("id" => 500,"categorypath" => "level1/eatable/fruits", "product" => "mango"),
    array("id" => 600,"categorypath" => "level1/eatable/vegetables", "product" => "spinach"),
    array("id" => 700,"categorypath" => "level2/baby items/toys", "product" => "puzzle block"),
    array("id" => 800,"categorypath" => "level2/baby items/toys", "product" => "trucks and cars"),
    array("id" => 900,"categorypath" => "level2/baby items/clothes", "product" => "shirts"),
    array("id" => 1000,"categorypath" => "level1/powders", "product" => "Womens powder"),
    array("id" => 1100,"categorypath" => "level1/oils/groundnut", "product" => "GN oil"), 
);

$jsonStruct = array();

function jsonCreateStruct(){
    GLOBAL $items;
    for($c=0; $c<count($items); $c++){
        $categ = $items[$c]["categorypath"];
        insertJson($categ, $items[$c]);
        
    }
}

function insertJson($catg, $itm){
    GLOBAL $jsonStruct;
    $exp = explode("/",$catg);
    print_r("\n\n\n $catg \n");
    if(count($exp) == 1){
        print_r("Level 1 \n");
        if(!isset($jsonStruct[0])){
            $jsonStruct[0]["categoryName"] = $exp[0];
            $jsonStruct[0]["products"] = array($itm);
            print_r("\nCreated:: $exp[0]");
        }else{
           $notFound = true;
           for($j=0; $j<count($jsonStruct); $j++){
                $catgName = $jsonStruct[$j]["categoryName"];
                print_r("\nFound: $catgName");
                if($catgName == $exp[0]){
                    $notFound = false;
                    if($jsonStruct[$j]["products"]){
                        array_push($jsonStruct[$j]["products"],array($itm));
                    }else{
                        $jsonStruct[$j]["products"] = array();
                        array_push($jsonStruct[$j]["products"],array($itm));
                    }
                }
            }
            if($notFound){
                print_r("\nNotFound\n");
                array_push($jsonStruct,array("categoryName"=> $exp[0], "products" => array($itm)));
            }
            
        }
        
    }
    if(count($exp) == 2){
        print_r("Level 2 \n");
        if(!isset($jsonStruct[0])){
            $jsonStruct[0]["categoryName"] = $exp[0];
            $jsonStruct[0]["categorypath"] = array("categoryName" => $exp[1], "products" => array($itm));
            print_r("\nCreated:: $exp[0] / $exp[1]");
        }else{
            $notFound1 = true;
            $notFound2 = true;
            $indexLevel = null;
           for($j=0; $j<count($jsonStruct); $j++){
               $catgName1 = $jsonStruct[$j]["categoryName"];
                print_r("\nFound: $catgName1");
                if($catgName1 == $exp[0]){
                   $notFound1 = false;
                   $indexLevel = $j;
                   if(isset($jsonStruct[$j]["categorypath"])){
                       $level1 = $jsonStruct[$j]["categorypath"];
                       for($m=0; $m<count($level1); $m++){
                           if(isset($level1[$m]["categoryName"])){
                              $catgName2 = $level1[$m]["categoryName"];
                               print_r("\nFound: $catgName2");
                               if($catgName2 == $exp[1]){
                                   $notFound2 = false;
                                   if($level1[$m]["products"]){
                                       array_push($jsonStruct[$j]["categorypath"][$m]["products"],array($itm));
                                   }else{
                                       $jsonStruct[$j]["categorypath"][$m]["products"] = array();
                                       array_push($jsonStruct[$j]["categorypath"][$m]["products"],array($itm));
                                   }
                                   
                               } 
                           }
                       }
                   } 
                }
           }
           if($notFound1){
               print_r("\nNotFound1\n");
               array_push($jsonStruct,array("categoryName"=> $exp[0], "categorypath" => array("categoryName" => $exp[1],"products" => array($itm))));
           }else if($notFound2){
               print_r("\nNotFound2\n");
              // $jsonStruct[$indexLevel]["categorypath"] = array("categoryName"=> $exp[1], "products" => array($itm));
               $jsonStruct[$indexLevel]["categorypath"] = array();
               array_push($jsonStruct[$indexLevel]["categorypath"], array("categoryName"=> $exp[1], "products" => array($itm)));
           }
        } 
    }
    if(count($exp) == 3){
        print_r("Level 3 \n");
        if(!isset($jsonStruct[0])){
            $jsonStruct[0]["categoryName"] = $exp[0];
            $jsonStruct[0]["categorypath"] = array("categoryName" => $exp[1], "categorypath" => array("categoryName" => $exp[2], "products" => array($itm)));
            print_r("\nCreated:: $exp[0] / $exp[1] / $exp[2]");
        }else{
            $notFound1 = true;
            $notFound2 = true;
            $notFound3 = true;
            $indexLevel1 = null;
            $indexLevel2 = null;
           for($j=0; $j<count($jsonStruct); $j++){
               $catgName1 = $jsonStruct[$j]["categoryName"];
                print_r("\nFound: $catgName1");
                if($catgName1 == $exp[0]){
                   $notFound1 = false;
                   $indexLevel1 = $j;
                   if(isset($jsonStruct[$j]["categorypath"])){
                       $level2 = $jsonStruct[$j]["categorypath"];
                       for($m=0; $m<count($level2); $m++){
                           if(isset($level2[$m]["categoryName"])){
                              $catgName2 = $level2[$m]["categoryName"];
                               print_r("\nFound: $catgName2");
                               if($catgName2 == $exp[1]){
                                   $notFound2 = false;
                                   $indexLevel2 = $m;
                                   if(isset($level2[$m]["categorypath"])){
                                      $level3 = $level2[$m]["categorypath"];
                                      for($n=0; $n<count($level3); $n++){
                                          //print_r($level3["categoryName"]);
                                          if(isset($level3["categoryName"])){
                                             $catgName3 = $level3["categoryName"];
                                             print_r("\ncatgName3: ". $catgName3);
                                              if($catgName3 == $exp[2]){
                                                  $notFound3 = false;
                                                  if($level3["products"]){
                                                      print_r("\npushing into array\n");
                                                      array_push($jsonStruct[$j]["categorypath"][$m]["categorypath"]["products"],array($itm));
                                                  }else{
                                                      print_r("\ncreate new and pushing into array\n");
                                                      $jsonStruct[$j]["categorypath"][$m]["categorypath"][$n]["products"] = array();
                                                      array_push($jsonStruct[$j]["categorypath"][$m]["categorypath"]["products"],array($itm));
                                                  }
                                                  
                                              } 
                                          }
                                          
                                      }
                                   }
                               } 
                           }
                           
                       }
                   } 
                }
           }
           if($notFound1){
               print_r("\nNotFound1\n");
               array_push($jsonStruct, array("categoryName"=> $exp[0], "categorypath" => array("categoryName" => $exp[1],"products" => array($itm))));
           }else if($notFound2){
               print_r("\nNotFound2\n");
               if(!$jsonStruct[$indexLevel1]["categorypath"]){
                   $jsonStruct[$indexLevel1]["categorypath"] = array();
               }
               array_push($jsonStruct[$indexLevel1]["categorypath"], array("categoryName"=> $exp[1], "categorypath" => array("categoryName" => $exp[2], "products" => array($itm))));
           }else if($notFound3){
               print_r("\nNotFound3\n");
               //$jsonStruct[$indexLevel1]["categorypath"][$indexLevel2]["categorypath"] = array("categoryName"=> $exp[2], "products" => array($itm));
              if(!$jsonStruct[$indexLevel1]["categorypath"][$indexLevel2]["categorypath"]){
                  $jsonStruct[$indexLevel1]["categorypath"][$indexLevel2]["categorypath"] = array();
              }
               array_push($jsonStruct[$indexLevel1]["categorypath"][$indexLevel2]["categorypath"], array("categoryName"=> $exp[2], "products" => array($itm)));
           }
        } 
    }
}


jsonCreateStruct();
print_r("----------------------------------------");
print_r($jsonStruct); 
// echo json_encode($jsonStruct);

 

I have now reached a point where I desperately need help from experts.

 

Share this post


Link to post
Share on other sites

You can use json_encode to do the conversion. It would be easier to restructure your array so it can be json encoded.

Share this post


Link to post
Share on other sites

I had a blog post bookmarked that covered creating a tree structure from a list that I was going to link, but it seems it's no longer online.  I guess maybe I should make my own some day.

Transforming your list of items into a structure for your json can be done with relative ease by making use of references and a lookup table.

For your particular problem, it's best broken down into two separate steps.

  1. Group your products by category.
  2. Nest your list of categories into your tree structure.

Grouping your products is easy, just combine all the products with the same categorypath into an array.

// First, group products into their categories.
$categoryList = [];
foreach ($itemList as $item){
    $categoryList[$item['categorypath']][] = [
        'id' => $item['id']
        , 'path' => $item['categorypath']
        , 'prodname' => $item['product']
    ];
}

After that, you have a nice list of all your products.  In $categoryList the key will be each of your unique category path's and the value will be a list of products that belong to that category.

Now, you need to take that array and structure it into your tree.  To do this, you create two arrays, one that will hold your final tree structure and another that you use to lookup existing entries to make modifications to them.

In order for your modifications to have an effect on the tree, you need to make sure both your lookup array and tree structure array refer to the same underlying data which is accomplished via references.

// Now, create a tree structure out of the categories
$jsonTree = ['category'=>[]];
$lookupTable = [];
foreach ($categoryList as $category=>$productList){
    $componentList = explode('/', $category);

    $path = '';
    $parent = &$jsonTree;
    do {
        $component = array_shift($componentList);
        $path .= $component.'/';

        $entry = &$lookupTable[$path];
        if (!$entry){
            $entry = [
                'categoryName' => $component
            ];

            $parent['category'][] = &$entry;
        }

        $parent = &$entry;
    } while ($componentList);

    $entry['products'] = $productList;
}

This loops through your list of categories and for each one does the following steps:

  1. Split the category path into it's individual components
  2. Create an initial parent reference to the root of your tree structure.
  3. Rebuild the path one component at a time.  For each component during this process
    1. Combine the current component with the previous ones to get a partial path
    2. Create a reference to a key for that partial path in $lookupTable and assign the reference to $entry
    3. Check if the key already exists or not.  If not:
      1. Create the category entry
      2. Assign the category to it's parent's list of sub-categories
    4. Re-assign the parent reference to the current category entry.  This way on the next iteration when we assign the category to $parent['category'] it will be made a child of the category from this iteration.
  4. At the end of the path rebuild, $entry is a reference to the last category entry.  Assign the product list to that entry.

At the end of all that, you can then just json_encode your tree structure to get the output you want.

By using references along with $lookupTable with unique index keys it's easy to find a reference to what might otherwise be a deeply nested category in your tree structure.  You can then manipulate that reference as necessary to make the changes necessary to generate your tree structure.

 

OP's SO Post, for reference.

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.