php вставка данных в многомерный массив по ключам - PullRequest
3 голосов
/ 21 июня 2019

Я пытаюсь вставить данные в многомерный массив, но это заставляет меня бороться. Я не могу это сделать. Это так смущает меня.

У меня есть массив "tree":

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

И массив пути, который я должен использовать для вставки данных:

$path = array(11,5);

Результат должен быть:

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

Это должно работать с любым многомерным массивом (n-мерным).

Как примечание, вставка всегда будет происходить в одну из самых глубоких ветвей дерева. Например, если дерево является трехмерным массивом, переменная пути наверняка будет иметь 3 значения, и вставка будет в одну из n трехмерных ветвей, которые мог бы иметь массив.

Я бы напечатал здесь то, что сделал, но не так уж и много. Я не знаю, стоит ли мне выбирать рекурсивную функцию для этого или другим способом.

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 21 июня 2019

Метод 1

Вы можете использовать pass by reference с 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

Метод 2

С помощью функции

$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;
}
1 голос
/ 21 июня 2019

Другой вариант создания рекурсивной функции - хранить массив, похожий на крошку, чтобы отслеживать индексы текущего пути.Затем сравните массив с массивом путей и, если они равны, присвойте значение.

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

1 голос
/ 21 июня 2019

Ну, вам просто нужна рекурсивная функция и работа с массивом, передаваемым по ref, что-то вроде ...

$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;
}

Печать ...

array(2) {
  [10]=>
  array(0) {
  }
  [11]=>
  array(3) {
    [4]=>
    array(0) {
    }
    [5]=>
    array(1) {
      [0]=>
      string(13) "Awesome value"
    }
    [6]=>
    array(0) {
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...