【问题标题】:How to recursively create a multidimensional array?如何递归创建多维数组?
【发布时间】:2010-11-27 20:53:25
【问题描述】:

我正在尝试创建一个多维数组,其部分由字符串确定。我使用.作为分隔符,每个部分(最后一个除外)都应该是一个数组
例如:

config.debug.router.strictMode = true

我想要的结果与我输入时一样:

$arr = array('config' => array('debug' => array('router' => array('strictMode' => true))));

这个问题真的让我陷入困境,感谢任何帮助。谢谢!

【问题讨论】:

    标签: php recursion multidimensional-array


    【解决方案1】:

    我说将所有内容拆分,从值开始,然后从那里向后工作,每次都将您拥有的内容包装在另一个数组中。像这样:

    $s = 'config.debug.router.strictMode = true';
    list($parts, $value) = explode(' = ', $s);
    
    $parts = explode('.', $parts);
    while($parts) {
       $value = array(array_pop($parts) => $value);
    }
    
    print_r($parts);
    

    一定要重写它,让它有错误检查。

    【讨论】:

    • 这很好用,但我很好奇我应该检查的可能错误。
    • 如果您想解析/存储多行,这看起来会中断。
    • Arms:例如,如果行中没有“=”,它将中断。基本上,与语法不匹配的行会导致我的脚本抛出 php 错误。你会想要让它更加宽容(比如不需要等号旁边的空格)并以某种有意义的方式处理错误,而不是 php 错误,比如“foreach() 的参数无效”。
    • 这应该被标记为最佳答案!简洁大方!
    【解决方案2】:

    假设我们已经拥有$key$val 中的键和值,那么你可以这样做:

    $key = 'config.debug.router.strictMode';
    $val = true;
    $path = explode('.', $key);
    

    从左到右构建数组:

    $arr = array();
    $tmp = &$arr;
    foreach ($path as $segment) {
        $tmp[$segment] = array();
        $tmp = &$tmp[$segment];
    }
    $tmp = $val;
    

    从右到左:

    $arr = array();
    $tmp = $val;
    while ($segment = array_pop($path)) {
        $tmp = array($segment => $tmp);
    }
    $arr = $tmp;
    

    【讨论】:

      【解决方案3】:
      // The attribute to the right of the equals sign
      $rightOfEquals = true; 
      
      $leftOfEquals = "config.debug.router.strictMode";
      
      // Array of identifiers
      $identifiers = explode(".", $leftOfEquals);
      
      // How many 'identifiers' we have
      $numIdentifiers = count($identifiers);
      
      
      // Iterate through each identifier backwards
      // We do this backwards because we want the "innermost" array element
      // to be defined first.
      for ($i = ($numIdentifiers - 1); $i  >=0; $i--)
      {
      
         // If we are looking at the "last" identifier, then we know what its
         // value is. It is the thing directly to the right of the equals sign.
         if ($i == ($numIdentifiers - 1)) 
         {   
            $a = array($identifiers[$i] => $rightOfEquals);
         }   
         // Otherwise, we recursively append our new attribute to the beginning of the array.
         else
         {   
            $a = array($identifiers[$i] => $a);
         }   
      
      }
      
      print_r($a);
      

      【讨论】:

        【解决方案4】:

        Gumbo 的回答看起来不错。

        但是,您似乎想要解析一个典型的 .ini 文件。

        考虑使用库代码而不是自己编写代码。

        例如,Zend_Config 很好地处理了这种事情。

        【讨论】:

          【解决方案5】:

          我真的很喜欢 JasonWolf 对此的回答。

          至于可能的错误:是的,但他提供了一个很棒的想法,现在由读者来证明它是无懈可击的。

          我的需要更基本一点:从一个分隔列表,创建一个 MD 数组。我稍微修改了他的代码来给我这个。这个版本会给你一个有或没有定义字符串的数组,甚至是一个没有分隔符的字符串。

          我希望有人可以做得更好。

          $parts = "config.debug.router.strictMode";
          
          $parts = explode(".", $parts);
          
          $value = null;
          
          while($parts) {
            $value = array(array_pop($parts) => $value);
          }
          
          
          print_r($value);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-12-08
            • 2011-11-13
            • 1970-01-01
            • 2017-12-28
            • 2017-11-28
            • 2016-03-27
            • 2019-02-20
            • 2017-02-26
            相关资源
            最近更新 更多