0

I have an array like this

Array
(
    [0] => Array
        (
            [id] => 1
            [category_name] => One
            [parent_id] => 
            [children_recursive] => Array
                (
                )
        )
    [1] => Array
        (
            [id] => 2
            [category_name] => Two
            [parent_id] =>
            [children_recursive] => Array
                (
                )
        )
    [2] => Array
        (
            [id] => 3
            [category_name] => Three
            [parent_id] => 
            [children_recursive] => Array
                (
                    [0] => Array
                        (
                            [id] => 17
                            [category_name] => Three and one
                            [parent_id] => 3
                            [children_recursive] => Array
                                (
                                )
                        )
                    [1] => Array
                        (
                            [id] => 19
                            [category_name] => Three and two
                            [parent_id] => 3
                            [children_recursive] => Array
                                (
                                    [0] => Array
                                        (
                                            [id] => 21
                                            [category_name] => Three and two and one
                                            [parent_id] => 19
                                            [children_recursive] => Array
                                                (
                                                )
                                        )
                                )
                        )
                    [2] => Array
                        (
                            [id] => 20
                            [category_name] => Three and three
                            [parent_id] => 3
                            [children_recursive] => Array
                                (
                                )
                        )
                )
        )
    [3] => Array
        (
            [id] => 4
            [category_name] => Four
            [parent_id] => 
            [children_recursive] => Array
                (
                    [0] => Array
                        (
                            [id] => 18
                            [category_name] => Four and one
                            [parent_id] => 4
                            [children_recursive] => Array
                                (
                                )
                        )
                )
        )
)

What I want to from this array

One
Two
Three
Three >> Three and one
Three >> Three and two
Three >> Three and two >> Three and two and one
Three >> Three and three
Four
Four >> Four and one

What I have tried

$category = myarray;
renderNode($category);

function renderNode($node) {
        foreach($node as $cat){
            echo $cat['category_name'].'<br >';
            if(!empty($cat[children_recursive'])){
                renderNode($cat[children_recursive']);
            }
        }
    }

And My output is

One
Two
Three
Three and one
Three and two
Three and two and one
Three and three
Four
Four and one

Edit here is the full array list using var_export so you can just copay and paste

array (
  0 => 
  array (
    'id' => 1,
    'category_name' => 'One',
    'parent_id' => NULL,
    'children_recursive' => 
    array (
    ),
  ),
  1 => 
  array (
    'id' => 2,
    'category_name' => 'Two',
    'parent_id' => NULL,
    'children_recursive' => 
    array (
    ),
  ),
  2 => 
  array (
    'id' => 3,
    'category_name' => 'Three',
    'parent_id' => NULL,
    'children_recursive' => 
    array (
      0 => 
      array (
        'id' => 17,
        'category_name' => 'Three and one',
        'parent_id' => 3,
        'children_recursive' => 
        array (
        ),
      ),
      1 => 
      array (
        'id' => 19,
        'category_name' => 'Three and two',
        'parent_id' => 3,
        'children_recursive' => 
        array (
          0 => 
          array (
            'id' => 21,
            'category_name' => 'Three and two and one',
            'parent_id' => 19,
            'children_recursive' => 
            array (
            ),
          ),
        ),
      ),
      2 => 
      array (
        'id' => 20,
        'category_name' => 'Three and three',
        'parent_id' => 3,
        'children_recursive' => 
        array (
        ),
      ),
    ),
  ),
  3 => 
  array (
    'id' => 4,
    'category_name' => 'Four',
    'parent_id' => NULL,
    'children_recursive' => 
    array (
      0 => 
      array (
        'id' => 18,
        'category_name' => 'Four and one',
        'parent_id' => 4,
        'children_recursive' => 
        array (
        ),
      ),
    ),
  ),
)
2
  • var_dump is useless for representing source data, try to use var_export, so the array can be copy and paste. Commented Dec 6, 2016 at 13:18
  • @sevavietl I add my array using var_export for. see my updated question Commented Dec 6, 2016 at 13:25

3 Answers 3

1

Something like that:

function getValues($array, $prefix = '')
{
    $values = [];

    foreach ($array as $value) {
        $values[] = $prefix . $value['category_name'];

        if (!empty($value['children_recursive'])) {
            $values = array_merge($values, getValues($value['children_recursive'], $prefix . $value['category_name'] . ' >> '));
        }
    }

    return $values;
}

implode('<br>', getValues($array));
Sign up to request clarification or add additional context in comments.

3 Comments

array_merge(): Argument #2 is not an array
its my mistake. I write return statement inside loop :P
1

You can use RecursiveArrayIterator. You need to extend it like this:

class RecursiveChildrenIterator extends RecursiveArrayIterator
{
    public function hasChildren()
    {
        return !empty($this->current()['children_recursive']);
    }

    public function getChildren()
    {
        return new static($this->current()['children_recursive']);
    }
}

Having this class you can simply loop with one foreach:

$iterator = new RecursiveIteratorIterator(
    new RecursiveChildrenIterator($array),
    RecursiveIteratorIterator::SELF_FIRST  
);

$result = [];
$current = [];
foreach ($iterator as $item) {
    $current[$iterator->getDepth()] = $item['category_name'];

    if (!$iterator->hasChildren()) {
        $result[] = implode(
            '>>',
            array_slice($current, 0, $iterator->getDepth() + 1)
        );
    }
}

Take a notice on RecursiveIteratorIterator::SELF_FIRST flag passed to RecursiveIteratorIterator.

Here is working demo.

Addition:

I actually misread you desired array, so to get the one you wanted remove the condition:

foreach ($iterator as $item) {
    $current[$iterator->getDepth()] = $item['category_name'];

    $result[] = implode(
        '>>',
        array_slice($current, 0, $iterator->getDepth() + 1)
    );
} 

Here is working demo.

You can read more about iterators.

Comments

0
$category = myarray;
renderNode($category);

function renderNode($parent_category_name = '' ,$node) {
        foreach($node as $cat){
            echo $parent_category_name.$cat['category_name'].'<br >';
            if(!empty($cat[children_recursive'])){
                renderNode($parent_category_name .$cat['category_name'] ." >> ", $cat[children_recursive']);
            }
        }
    }

1 Comment

in the future, you may want to add some context ( comments ) regarding the code you are sharing as the answer. FYI

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.