2

Hi I have this simple php array containing category hierarchy

<?php

$categories = [
    'Games',
    '-Sports',
    '--Footbal',
    '--Basketball',
    '-Action',
    '--FPS',
    '--RPG',
    '-SIM',
];

Once echo, it will looks like this (A simple category hierarychy):

Games
-Sports
--Footbal
--Basketball
-Action
--FPS
--RPG
-SIM

Currently I want to use the Bootstrap Tree plugin by https://github.com/jonmiles/bootstrap-treeview and need to prepare my data to look like this

var tree = [
  {
    text: "Games",
    nodes: [
      {
        text: "Sports",
        nodes: [
          {
            text: "Footbal"
          },
          {
            text: "Basketball"
          }
        ]
      },
      {
        text: "Action",
        nodes: [
          {
            text: "FPS"
          },
          {
            text: "RPG"
          }
        ]
      },
      {
        text: "SIM"
      }
    ]
  }
];

I understand I need to build an array first and later convert it into JSON. Question is how do I convert my existing array into compatible array for the required JSON?

My code so far

<?php

$categories = [
    'Games',
    '-Sports',
    '--Footbal',
    '--Basketball',
    '-Action',
    '--FPS',
    '--RPG',
    '-SIM',
];

$tree_key = 0;

if (!empty($categories)) {
            foreach ($categories as $category) {

                $tree_label = $category;

                $count = substr_count($tree_label, '-');

                //if no dash (-) found, make it parent category
                if (empty($count)) {
                    $tree_key = $category;
                    $tree_array[$tree_key] = ['text'=>$category];
                }
                else
                {
                    //if one dash found, make it child of previous parent category
                    if ($count === 1) {
                        $tree_array[$tree_key]['nodes'][] = ['text'=>$category];
                    } else {

                    }
                }


            }
        }

Thanks guys for helping!

4
  • Do you just need this one json object, or do you want code that can do it no matter what the array is Commented Sep 20, 2017 at 14:42
  • As a Tree is a recursive data model I would suggest a recursive approach to this problem Commented Sep 20, 2017 at 14:42
  • @MatthewBergwall depending the number of the dash (-), I wan to keep it nested, but usually the data is pretty much like the example above, so if I can achieve that already good :) Commented Sep 20, 2017 at 14:48
  • @gogaz recursive approach, can I know what should I google it? Commented Sep 20, 2017 at 14:49

1 Answer 1

1

Try this:

function buildTree($data, $currentDepth = 0, $startIndex = 0) {
    $tree = array();
    foreach ($data as $i=>$c) {
        if ($i < $startIndex) {
            continue;
        }

        $depth = 0;
        if (preg_match('/^([-]*)/', $c, $m)) {
            $depth = strlen($m[1]);
        }

        if ($depth < $currentDepth) {
            break;
        } elseif ($depth != $currentDepth) {
            continue;
        }

        $node = array('text' => preg_replace('/^[-]*/', '', $c));
        $nodes = buildTree($data, $depth + 1, $i + 1);
        if (count($nodes) > 0) {    
            $node['nodes'] = $nodes;
        }

        $tree[] = $node;
    }
    return $tree;
}

$categories = [
    'Games',
    '-Sports',
    '--Footbal',
    '--Basketball',
    '-Action',
    '--FPS',
    '--RPG',
    '-SIM',
];

echo json_encode( buildTree($categories), JSON_PRETTY_PRINT );

Online demo

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks your answer works perfectly, looking at your code I wonder how I can reach the level to write this kind of code. Thanks again mr @brevis

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.