0

Here is an array. Once a new element comes in with parent_uuid, I need to add that to the corresponding position, that is to the children of the item which has uuid value as parent_uuid value. The children then can have other children and if that is specified, I need to insert it to the particular parent. I think for this I need to search to the multidimensional array with the parent_uuid value. How can I do this and insert in PHP?

Array
(
    [0] => Array
        (
            [id] => 1
            [uuid] => ef4b72ae-012a-4b2c-88b2-d4bf8726fcb9
            [parent_uuid] => 
            [name] => First Parent
            [children] => Array
                (
                )
        )

    [1] => Array
        (
            [id] => 2
            [uuid] => 74bd4b37-6a20-4579-99a3-ce56b0bc28a7
            [parent_uuid] => 
            [name] => Second Parent
            [children] => Array
                (
                    [0] => Array
                        (
                            [id] => 3
                            [uuid] => f87c6d5c-93ec-40bf-a04d-c925dd1e0aca
                            [parent_uuid] => 74bd4b37-6a20-4579-99a3-ce56b0bc28a7
                            [name] => First Child
                            [children] => Array
                                (
                                )

                        )

                    [1] => Array
                        (
                            [id] => 4
                            [uuid] => cb2b3d9d-867c-40a0-9254-05b466859db1
                            [parent_uuid] => 74bd4b37-6a20-4579-99a3-ce56b0bc28a7
                            [name] => Second Child
                            [children] => Array
                                (
                                )

                        )

                )

        )

)
7
  • 3
    If the concession is that "basically, this is a tree structure", it sounds like the obvious solution is to actually use a tree, with all the searching benefit offered by a real data structure. Commented Sep 26, 2017 at 16:55
  • seems like this is a repeat question codereview.stackexchange.com/questions/44864/… Commented Sep 26, 2017 at 16:57
  • @Mike'Pomax'Kamermans , but how to do that in PHP ? Commented Sep 26, 2017 at 17:04
  • PHP supports OOP so worst case you just write your own Tree class (or rather Node class, and your tree is just "a node with children" because that's how trees work). But I bet there are already generic tree implementations available through PEAR etc. Commented Sep 26, 2017 at 17:08
  • as @mike suggested the parent_uuid is not needed : the position of an element in the tree is enough to determine what is the parent uid. suppressing this key will make thing simpler. Commented Sep 26, 2017 at 17:14

2 Answers 2

1

I think you need some kind of recursive function, here is my messy example.

<?php

header('Content-type: text/plain');

$data = array (
  0 => 
  array (
    'id' => 1,
    'uuid' => 'ef4b72ae-012a-4b2c-88b2-d4bf8726fcb9',
    'parent_uuid' => '',
    'name' => 'First Parent',
    'children' => 
    array (
    ),
  ),
  1 => 
  array (
    'id' => 2,
    'uuid' => '74bd4b37-6a20-4579-99a3-ce56b0bc28a7',
    'parent_uuid' => '',
    'name' => 'Second Parent',
    'children' => 
    array (
      0 => 
      array (
        'id' => 3,
        'uuid' => 'f87c6d5c-93ec-40bf-a04d-c925dd1e0aca',
        'parent_uuid' => '74bd4b37-6a20-4579-99a3-ce56b0bc28a7',
        'name' => 'First Child',
        'children' => 
        array (
        ),
      ),
      1 => 
      array (
        'id' => 4,
        'uuid' => 'cb2b3d9d-867c-40a0-9254-05b466859db1',
        'parent_uuid' => '74bd4b37-6a20-4579-99a3-ce56b0bc28a7',
        'name' => 'Second Child',
        'children' => 
        array (
        ),
      ),
    ),
  ),
);

function arrayAddChild(&$data, $child) {
    if (!isset($data) || !is_array($data) || empty($data)) {
        return false;
    }
    foreach ($data as $key => $value) {
        if ($value['uuid'] === $child['parent_uuid']) {
            $data[$key]['children'][] = $child;
            return true;
        }
        if(arrayAddChild($data[$key]['children'], $child)) {
            return true;
        }
    }
    return false;
}

var_export(arrayAddChild($data, [
                        'id' => 31,
                        'uuid' => '31',
                        'parent_uuid' => 'cb2b3d9d-867c-40a0-9254-05b466859db1',
                        'name' => 'Second Child',
                        'children' => []
                      ]
                      ));

var_export(arrayAddChild($data, [
                        'id' => 32,
                        'uuid' => '32',
                        'parent_uuid' => '31',
                        'name' => 'Second Child',
                        'children' => []
                      ]
                      ));

var_export(arrayAddChild($data, [
                        'id' => 33,
                        'uuid' => '33',
                        'parent_uuid' => '32',
                        'name' => 'Second Child',
                        'children' => []
                      ]
                      ));
var_export(arrayAddChild($data, [
                        'id' => 34,
                        'uuid' => '34',
                        'parent_uuid' => '33',
                        'name' => 'Second Child',
                        'children' => []
                      ]
                      ));
var_export(arrayAddChild($data, [
                        'id' => 35,
                        'uuid' => '35',
                        'parent_uuid' => '34',
                        'name' => 'Second Child',
                        'children' => []
                      ]
                      ));
var_export(arrayAddChild($data, [
                        'id' => 36,
                        'uuid' => '36',
                        'parent_uuid' => '35',
                        'name' => 'Second Child',
                        'children' => []
                      ]
                      ));


var_export($data);
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks a lot, Oleg. This works great with the data I have given. But if there is one more inner child is present, it will not add the children to that. Can you please modify as it takes N level of depth?
That might work: function arrayAddChild(&$data, $child) { foreach ($data as $key => $value) { if ($value['uuid'] === $child['parent_uuid']) { $data[$key]['children'][] = $child; return true; } if(arrayAddChild($data[$key]['children'], $child)) { return true; } } return false; }
The problem is , if am item has two children and if I try to add another children to any of the child, it is showing "Invalid argument suppiied for foerach". The above modifications doesn't return any error, but it is not adding the child.
Very strange, I've just changed my answer, try to run it. Works fine in php7.
You might get "Invalid argument suppiied for foerach" beacause some of your items dont have 'children' property, or 'children' is not an array. I've edited my answer again.
|
1

this is the structure you need

$Array["ef4b72ae-012a-4b2c-88b2-d4bf8726fcb9"]['name'] = "First Parent";
$Array["ef4b72ae-012a-4b2c-88b2-d4bf8726fcb9"]['children'] = [];

$Array["74bd4b37-6a20-4579-99a3-ce56b0bc28a7"]['name'] = "Second Parent";
$Array["74bd4b37-6a20-4579-99a3-ce56b0bc28a7"]['children']["f87c6d5c-93ec-40bf-a04d-c925dd1e0aca"]['name'] = "First Child";
$Array["74bd4b37-6a20-4579-99a3-ce56b0bc28a7"]['children']["f87c6d5c-93ec-40bf-a04d-c925dd1e0aca"]['children'] = [];

$Array["74bd4b37-6a20-4579-99a3-ce56b0bc28a7"]['children']["cb2b3d9d-867c-40a0-9254-05b466859db1"]['name'] = "Second Child";
$Array["74bd4b37-6a20-4579-99a3-ce56b0bc28a7"]['children']["cb2b3d9d-867c-40a0-9254-05b466859db1"]['children'] = [];

and this is if you really need 'name' or any complementary info you need to store with each item. If it is just about a tree structure of uid, get rid of 'name' and 'children' keys

have not found a standard php function to recursively search for a given key (anyone ?)

so here is the function you need

    function insertItem($newItem,$uidParent,$array) {
    foreach ($array as $uid => $content) {
        if ($uid == $uidParent) { // parent found, item insert
            $array[$uid]['children'][$newItem['uid']]['name'] = $newItem['name'];
            $array[$uid]['children'][$newItem['uid']]['children'] = [];
        } elseif (!empty($content['children'])) { // recursively search the tree
            $array[$uid]['children'] = insertItem($newItem,$uidParent,$content['children']);
        }
    }
    return $array;
}

$newItem['name'] = "new item";
$newItem['uid'] = "f87c6d5c-93ec-40bf-a04d-c925dd1e0aca";
$uidParent = "cb2b3d9d-867c-40a0-9254-05b466859db1";
$Array = insertItem($newItem,$uidParent,$Array);

sandbox here

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.