1

I wrote a recursive function which relies on echo to work, and it works perfectly. But, to challenge myself, I wanted to make it return an array of processed values instead of echoing the values directly.

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

function printAll($a, $level = '', $values = []) {
    foreach($a as $v) {
        $values[] = $value = "{$level}{$v['id']}";
        if(!empty($v['children'])) {
            return printAll($v['children'], "{$value}.", $values);
        }
    }
    return $values;
}

But I'm getting unexpected results. This function currently returns an array that looks like this:

Array
(
    [0] => 1
    [1] => 1.2
    [2] => 1.5
    [3] => 1.5.3
)

But in this case, I'm expecting this:

Array
(
    [0] => 1
    [1] => 1.2
    [2] => 1.5
    [3] => 1.5.3
    [4] => 4
)

It looks like my recursive function only processes the very first value of $data and all of it's children, but never the rest of $data. I'm assuming this is because I am using return which ends the loop.

My question is, how can I make my printAll() function process the entire set of data, without overly complicating the function?

3
  • What have you tried to debug the problem? Commented Aug 28, 2020 at 14:44
  • i think you must add seconde parameter (true) in the json_decode, to avoid Cannot use object of type stdClass as array error Commented Aug 28, 2020 at 14:46
  • This looks like a wonderful exercise for test-driven development :) Commented Aug 28, 2020 at 14:46

2 Answers 2

3

The problem is that as you have

return printAll($v['children'], "{$value}.", $values);

part of the way through, this will ignore any further items in subsequent elements.

A quick fix would be to just add the new values into the current values and have the 1 return at the end of the routine...

$values += printAll($v['children'], "{$value}.", $values);
Sign up to request clarification or add additional context in comments.

1 Comment

If you return at the first item that has any sub items, you will never process the entire array.
1

You need to remove the return printAll(...) and add the value to the variable. Otherwise it will stop in the first value that has a 'children'

<?php

function printAll($a, $level = '', $values = []) {
    foreach($a as $v) {
        $values[] = $value = "{$level}{$v['id']}";
        if(!empty($v['children'])) {
            //Just remove this return and add to the variable you already have.
            $values = printAll($v['children'], "{$value}.", $values);
        }
    }
    return $values;
}

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

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.