3

I'm trying to insert data into a multidimensional array but it get's me struggled. I'm unable to do it. It's so confusing for me.

I have a "tree" array:

$tree = array(
               10 => array(),
               11 => array(
                         4 => array(),
                         5 => array(),
                         6 => array()
               )
        );

And the array of the path I have to use to insert the data:

$path = array(11,5);

The result should be:

$tree = array(
               10 => array(),
               11 => array(
                         4 => array(),
                         5 => array($data),
                         6 => array()
               )
        );

This must work with any multidmensional array (n-dimensional).

As a note, the insertion will always take place in one of the deepest branches of the tree. For example, if the tree is a three-dimensional array, the path variable will have 3 values for sure and the insertion will be in one of the n three-dimensional branches the array could have.

I would type here what I have done but is not so much. I event don't know if I should choose a recursive function to do it or other way.

Thanks in advance.

4
  • the input array can have more depth? like 4 => array( 1=>array(), 2=>array() ), Commented Jun 21, 2019 at 11:45
  • Yes, It may have any depth Commented Jun 21, 2019 at 11:49
  • in that case how you gonna decide $path? Commented Jun 21, 2019 at 11:50
  • The path variable is a know data. For example, in a 4-dimensional array, the $path should be something like array(11,2,5,7). The insertion will always be in the deepest index of one of the m branches the the tree array could have Commented Jun 21, 2019 at 11:54

3 Answers 3

1

Well, you just need a recursive function and work with the array passing by ref, something like...

$tree = [
    10 => [],
    11 => [
        4 => [],
        5 => [],
        6 => []
    ]
];

$path = [
    11,
    5,
    0
];

var_dump(insertIntoArr($tree, 'Awesome value', $path, $tree));

function insertIntoArr(&$chunk, $data, $path, &$original) {
    $key = array_shift($path);

    if (!empty($path)) {
        if (!isset($chunk[$key])) {
            throw new \Exception('OMG! This path does\'t exists, I can\'t continue...');
        }

        return insertIntoArr($chunk[$key], $data, $path, $original);
    }

    $chunk[$key] = $data;

    return $original;
}

Prints...

array(2) {
  [10]=>
  array(0) {
  }
  [11]=>
  array(3) {
    [4]=>
    array(0) {
    }
    [5]=>
    array(1) {
      [0]=>
      string(13) "Awesome value"
    }
    [6]=>
    array(0) {
    }
  }
}
Sign up to request clarification or add additional context in comments.

Comments

1

Method 1

You can use pass by reference with foreach

$tree = [
       10 => [],
       11 => [
                4 => [],
                5 => [],
                6 => []
       ]
    ];
$path = array(11,5,0);
$inseration = array('A','B');
$current = &$tree;
foreach($path as $key){
  $current = &$current[$key];
}
$current = $inseration;
echo '<pre>';
print_r($tree);

DEMO

Method 2

By using function

$tree = [
       10 => [],
       11 => [
                4 => [],
                5 => 'r',
                6 => []
       ]
    ];
$path = array(11,5);
$inseration = [1,2];
insertByKey($tree, $path, $inseration);

function insertByKey(&$array, $path, $inseration){
  $current = &$array;
  $key = array_shift($path);
  while($key > 0){
    $current = &$current[$key];
    $key = array_shift($path);
  }
  $current = $inseration;
}

Comments

1

Another option creating a recursive function is to store a breadcrumb like array to keep track of the indices of the current path. Then compare array with the path array and if they are equal assign the value.

function setByIndices(&$tree, $path, $data, $indices = []) {
    foreach ($tree as $k => &$v) {
        $indices[] = $k;
        if ($indices === $path) {
            $v = $data;
            return;
        }
        if (is_array($v)) setByIndices($v, $path, $data, $indices);
        array_pop($indices);
    }
}

setByIndices($tree, $path, $data);

Php demo

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.