0

I need to convert simple array to nested array according to specific rules. I've achived it but I'm looking for better solution.

SIMPLE:

array(4) {
  [0]=>
  array(2) {
    ["id"]=>
    string(2) "11"
    ["type"]=>
    int(3)
  }
  [1]=>
  array(2) {
    ["id"]=>
    string(2) "10"
    ["type"]=>
    int(2)
  }
  [2]=>
  array(2) {
    ["id"]=>
    string(1) "1"
    ["type"]=>
    int(1)
  }
  [3]=>
  array(2) {
    ["id"]=>
    string(1) "0"
    ["type"]=>
    int(1)
  }
}

EXPECTED EFFECT:

array(1) {
  [0]=>
  array(2) {
    ["type"]=>
    int(1)
    ["child"]=>
    array(1) {
      [1]=>
      array(2) {
        ["type"]=>
        int(1)
        ["child"]=>
        array(1) {
          [10]=>
          array(2) {
            ["type"]=>
            int(2)
            ["child"]=>
            array(1) {
              [11]=>
              array(2) {
                ["type"]=>
                int(3)
                ["child"]=>
                array(0) {
                }
              }
            }
          }
        }
      }
    }
  }
}

MY SOLUTION (not very satisfying):

$nestedArray = [];
    foreach ($simpleArray as $item)
    {
        if (!empty($nestedArray))
        {
            $array = $nestedArray;
            reset($array);
            $firstKey = key($array);
        }
        $nestedArray[$item['id']]['child'] = $nestedArray;
        $nestedArray[$item['id']]['type'] = $item['type'];
        if (!empty($firstKey))
        {
            unset($nestedArray[$firstKey]);
        }
    }

As I said, I'm looking for more elegant way to achieve that. Rule are very simply: every next item is child of previous.

3
  • 1
    So tell us: what is "not very satisfying" here? Without that, how do you expect us to suggest something "more satisfying"? Commented Jun 6, 2018 at 20:50
  • Do the example input and output relate to eachother? I don't see how their values match... Where does the "id" go? If anything, your last paragraph is describing the opposite: every next element is parent of previous (not child)... or what am I missing? Commented Jun 6, 2018 at 20:53
  • I do my best, but I think that my solution is very... basic. First array is related to second. First element of first array is the most nested element of second array. Commented Jun 6, 2018 at 21:03

1 Answer 1

2

You could use recursion:

function nest($arr) {
    return count($arr) ? ["type" => array_pop($arr)["type"], "child" => nest($arr)] : [];
}

With your example input, it would look like this:

$simpleArray = [
    ["id" => "11", "type" => 3],
    ["id" => "10", "type" => 2],
    ["id" => "1", "type" => 1],
    ["id" => "0", "type" => 1]
];

function nest($arr) {
    return count($arr) ? ["type" => array_pop($arr)["type"], "child" => nest($arr)] : [];
}

$nested = nest($simpleArray));

$nested will have the following value:

[
    "type" => 1,
    "child" => [
        "type" => 1,
        "child" => [
            "type" => 2,
            "child" => [
                "type" => 3,
                "child" => []
            ]
        ]
    ]
]
Sign up to request clarification or add additional context in comments.

1 Comment

That's what I need - recursion. I have to "make friends with it" ;-) Thanks guys!

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.