【问题标题】:Searching multi-dimensional array's keys using a another array使用另一个数组搜索多维数组键
【发布时间】:2011-11-24 19:14:18
【问题描述】:

有没有一种优雅的方法可以使用另一个数组作为键来从庞大的多维数组中获取值?

例如

$cats[A][A1][A11][A111] = $val;
$cats[A][A1][A11][A112] = $val;
$cats[A][A1][A12] = $val;
$cats[A][A1][A12][A121] = $val;
$cats[A][A2] = $val;
$cats[A][A2][A21] = $val;
$cats[A][A2][A22] = $val;
$cats[A][A2][A22][A221] = $val;
$cats[A][A2][A22][A222] = $val;

使用$keys = Array ('A', 'A2', 'A22', 'A221');访问来自$cats的值

不检查$keys 的长度并执行类似...

switch (count($keys)) {
   case 1: $val = $cats[$keys[0]]; break;
   case 2: $val = $cats[$key[0]][$key[1]]; break;
   case 3: $val = $cats[$key[0]][$key[1]][$key[2]]; break;
   ...
}

非常感谢。

【问题讨论】:

    标签: php arrays multidimensional-array


    【解决方案1】:

    为什么不使用递归?像这样的:

    function get_val($array, $keys) {
        if(empty($keys) || !is_array($keys) || !is_array($array)) return $array;
        else {
            $first_key = array_shift($keys);
            return get_val($array[$first_key], $keys);
        }
    }
    

    我最初是在循环中编写的,但由于某种原因将其更改为递归。确实,正如 yeoman 所说,递归函数比循环更有可能导致堆栈溢出,特别是如果您的数组足够大(PHP 确实支持结束递归),所以这里有一个循环应该实现相同的目的:

    // given a multidimensional array $array and single-dimensional array of keys $keys
    $desired_value = $array;
    while(count($keys) > 0) {
        $first_key = array_shift($keys);
        $desired_value = $desired_value[$first_key];
    }
    

    【讨论】:

    • 如果数组元素 $cats[A][A2][A22][A221] 不存在,我想添加它。在这种情况下,上面的循环会返回 null 吗?
    • 它会返回 null,是的。但它也会打印一个警告。您需要在访问之前检查 $desired_value[$first_key] 是否存在。如果它不存在,您可以将 $desired_value 显式设置为 null 并中断循环。然后在循环之后,您可以将新键添加到数组中。
    • 抱歉,这是一个 PHP 通知,而不是警告。根据您的 PHP 配置,您可能不会看到它,但最佳实践表明您无论如何都希望执行检查。
    • 现在我在编写设置函数时遇到了麻烦!使用相同的两个数组设置说 $cats[A][A2][A22][A221] 的值
    【解决方案2】:

    到目前为止还不错。否则,您将需要遍历数组并检查深度。为了使其动态化,我确信您在构建 $cats 时将键添加到 $keys 数组中。使用递归也可以解决它需要更多的步骤,更多的内存。

    【讨论】:

      【解决方案3】:

      jburbage 建议使用递归原则上是可以的,但据我所知,PHP 不支持 end-recursion。

      问题是关于“大规模”多维数组。

      由于“大规模”意味着除了巨大的整体大小之外还具有很大的深度,因此使用此解决方案可能会遇到堆栈溢出,因为通常可以在堆上创建比堆栈更深的数据结构可以通过 via递归。

      在这种情况下,从性能的角度来看,这种方法也是不可取的。

      只需重构 jburbage 的递归解决方案以循环工作,您就快到了 :-)

      这是 jburbage 的原始建议代码:

      function get_val($array, $keys) {
          if(empty($keys) || !is_array($keys) || !is_array($array)) return $array;
          else {
              $first_key = array_shift($keys);
              return get_val($array[$first_key], $keys);
          }
      }
      

      【讨论】:

      • 巨大的......好吧,它唯一的猫将高达 6 深
      • 好吧,对于 6 个级别,它真的不会有任何区别 :-)
      • 顺便说一句,@jburbage:哇,我不知道 PHP 现在有结束递归 - 看起来这门语言真的在成长 :-)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-27
      • 1970-01-01
      • 1970-01-01
      • 2013-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多