1

im having a little problem i need some help with. Im trying to convert a multidimensional array into a flatten array with nested set values right and left like so:

    $array = {
         'id' => 1
         'name' => 'john'
         'childs' => array(
             array(
                 'id' => 1
                 'name' => 'jane'
             )
          )        
    }

to

    $array = {
         array(
           'id' => 1,
           'name' => 'john'
           'left' => '1'
           'right' => '4'
         ),
         array(
           'id' => 1,
           'name' => 'jane'
           'left' => '2'
           'right' => '3'
         )
    }

Any help is appreciated!

4
  • A recursive function would do it. Commented Feb 22, 2012 at 22:10
  • yep a function would be nice. Commented Feb 22, 2012 at 22:11
  • 2
    So, what is your trouble writing the recursive function? You do know how to recurse? Commented Feb 22, 2012 at 22:13
  • An algorithm would be perfect Commented Feb 22, 2012 at 22:14

3 Answers 3

2

I asked a very similar question and got a result, so thought I'd send it on for you. I realise this is quite an old topic, but still worth getting an answer. I've included my data, but would be easily adapted for yours.

$JSON = '[{"id":1,"children":[{"id":2,"children":[{"id":3},{"id":4}]},{"id":5}]}]';
$cleanJSON = json_decode($JSON,true);

$a_newTree = array();       

function recurseTree($structure,$previousLeft) 
{
    global $a_newTree;  // Get global Variable to store results in.

    $indexed = array();                     // Bucket of results.       
    $indexed['id'] = $structure['id'];      // Set ID
    $indexed['left'] = $previousLeft + 1;   // Set Left

    $lastRight = $indexed['left'];

    $i_count = 0;
    if ($structure['children'])
    {
        foreach ($structure['children'] as $a_child)
        {
            $lastRight = recurseTree($structure['children'][$i_count],$lastRight);
            $i_count++;
        }
    }

    $indexed['right'] = $lastRight + 1;     // Set Right

    array_push($a_newTree,$indexed);        // Push onto stack

    return $indexed['right'];       
}

recurseTree($cleanJSON[0],0);
print_r($a_newTree);
Sign up to request clarification or add additional context in comments.

Comments

1
function restructRecursive($array, $left = 1) {
  if (isset($array['childs'])) {
    $result = array();
    foreach ($array['childs'] as $child) {
      $result = array_merge($result, restructRecursive($child, $left+1));
    }
    unset($array['childs']);
  }
  $array['left'] = $left;
  return array_merge(array($array), $result);
}

$newStruct = restructRecursive($oldStruct);

2 Comments

that function would only flatten my array. what i need is the left and right values for writing them into the database and reconstructing the tree
you can habdle left by increment it each function call, but what is "right"?
1

For anyone coming here and looking for a solution, loneTraceur's solution works fine. However, I needed one in OOP, so here is my version of it.

<?php

class NestedSet
{
    protected $tree = [];

    public function deconstruct($tree, $left = 0)
    {
        $this->flattenTree($tree, $left);
        return $this->tree;
    }

    protected function flattenTree($tree, $left)
    {
        $indexed = [];
        $indexed['id'] = $tree['id'];
        $indexed['_lft'] = $left + 1;

        $right = $indexed['_lft'];

        if (isset($tree['children']) && count($tree['children'])) {
            foreach ($tree['children'] as $child) {
                $right = $this->flattenTree($child, $right);
            }
        }

        $indexed['_rgt'] = $right + 1;

        $this->tree[] = $indexed;

        return $indexed['_rgt'];
    }
}

You would run it like this:

$NestedSet = new NestedSet;
$flat = $NestedSet->deconstruct($tree):

This code is based on the other answer.

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.