如何根据另一个数组访问数组维度?

时间:2013-12-26 12:06:38

标签: php arrays

使用以下代码:

<?php
  $array = array(
    array(
      array('a','b'),
      array('c')
    )
  );
  $location = array('0','1');
  $text = 'd';
?>

如果$location[]中的元素数量未知,我该如何实现以下目标?

$array[$location[0]][$location[1]][] = $text;

换句话说,如何为$array中的每个元素将一个维度转换为$location[]并在其中添加$ text。

3 个答案:

答案 0 :(得分:3)

可以通过以下方式实现:

  $array = array(
    array(
      array('a','b'),
      array('c')
    )
  );
  $location = array('0','1');
  $text = 'd';

$pointer = &$array;
foreach($location as $index)
{
   $pointer = &$pointer[$index];
}
$pointer[] = $text;
unset($pointer);//this is for safety

需要最后unset - 因为如果你忘记这样做,你可能会在稍后在代码中的某个地方使用$pointer时调试“神秘”的错误(这显然会有瞬间副作用,更改源数据并导致错误,而整个逻辑就可以了)

答案 1 :(得分:2)

阅读:

$value = $array;
foreach ($location as $index) {
    $value = $value[$index];
}

写:

$value =& $array;
foreach ($location as $index) {
    if (!array_key_exists($value, $index)) {
        $value[$index] = array();
    }
    $value =& $value[$index];
}
$value[] = $text;

答案 2 :(得分:1)

正如其他答案所示,可以通过引用来实现。但是,引用有点棘手,并且可能难以调试。当使用不同的数组执行相同的循环两次时,或者在嵌套循环时,结果can be rather baffling,更不用说通过引用分配在某些情况下也可以发出E_DEPRECATED通知(不在此特定示例中,但你永远不知道你的代码将如何进一步使用)。我建议使用递归函数,原因如下:

function getLocation(array $in, array $location)
{
    $in = $in[$location[0]];
    if (is_array($in) && count($location) > 1)
    {//more than 1 index left
        $location = array_slice($location,1);//or use unshift
        return getLocation($in, $location);
    }
    return $in;
}

这将是我的建议:它易于阅读,理解和维护 要向给定位置添加内容,可以更改此函数以递归(重新)分配值:

function addToLocation(array $in, array $location, $value)
{
    if (count($location) === 1)
    {//optionally add is_array checks
        $in[$location[0]][] = $value;
        return $in;
    }
    $in[$location[0]] = addToLocation(
                            $in[$location[0]],
                            array_slice($location, 1),
                            $value
    );
    return $in;
}

向上:

  • 更易于调试,使用和维护
  • 不需要使用更多的技能(函数签名说明了所有,真的)
  • 更安全(没有提及整理,很容易被遗忘)
  • 递归很有趣:)

下行/权衡:

  • 递归会产生一些额外的开销(更大的调用堆栈,本地范围保留在内存等等......)
  • 引用比通过索引访问数组更快(这需要HashTable查找,尽管这些是 O(1)操作,引用可以直接访问,不需要查找)

经常:防御性代码稍慢,资源密集程度更高。更快的方法更容易受到攻击,但难以维护。选择是你的。