Как получить динамический доступ к значениям в многомерном массиве - PullRequest
6 голосов
/ 19 сентября 2011
$first = array("a", "b" => array("c", "d" => array("e", "f")), "g", "h" => array("f"));
$second = array("b", "d", "f");
$string = "foobar";

Учитывая приведенный выше код, как я могу установить значение в $first для индексов, определенных в $second, для содержимого $string? Это означает, что для этого примера это должно быть $first["b"]["d"]["f"] = $string;, но содержимое $second и $first может иметь любую длину. $second всегда будет одномерным. Вот то, что я попробовал, но, похоже, не сработало, как планировалось:

$key = "";
$ptr = $first;
for($i = 0; $i < count($second); $i++)
{
    $ptr &= $ptr[$second[$i]];
    $key = key($ptr);
}
$first[$key] = $string;

Это будет делать $first["f"] = $string; вместо правильных многомерных индексов. Я думал, что с помощью key будет найдено местоположение в массиве, включая уровни, которые он уже сдвинул.

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

РЕДАКТИРОВАТЬ: Кроме того, я хотел бы сделать способ, который не использует eval.

1 Ответ

9 голосов
/ 19 сентября 2011

Это немного сложнее, чем это. Вы должны инициализировать каждый уровень, если он еще не существует. Но ваши настоящие проблемы:

  • Массив, к которому вы хотите добавить значение, находится в $ptr, а не в $first.
  • $x &= $y является сокращением для $x = $x & $y (побитовое И). То, что вы хотите, это x = &$y (назначить по ссылке).

Это должно сделать это:

function assign(&$array, $keys, $value) {
    $last_key = array_pop($keys);
    $tmp = &$array;
    foreach($keys as $key) {
        if(!isset($tmp[$key]) || !is_array($tmp[$key])) {
            $tmp[$key] = array();
        }
        $tmp = &$tmp[$key];
    }
    $tmp[$last_key] = $value;
    unset($tmp);
}

Использование:

assign($first, $second, $string);

DEMO

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...