2012-08-25 44 views
0

我一直在试图解决这个问题,但找不到我能理解的解决方案。递归地重命名数组键

我有这个数组,当我的应用程序通过读取动态配置文件加载时,这是在飞行中创建的。

我的问题是,我想要一个名为alias的数组,它将被拾取并重命名['@attr']所在的父数组。这里是一个例子来展示我的意思。

[database] => Array 
     (
      [0] => Array // Would be renamed to "production" 
       (
        [host] => test 
        [user] => test 
        [pass] => test 
        [name] => test 
        [port] => test 
        [@attr] => Array 
         (
          [alias] => production 
          [name] => live 
         ) 

       ) 

      [1] => Array // Would be renamed to "development" 
       (
        [user_data] => Array 
         (
          [0] => Array // Would be renamed to "three" 
           (
            [user] => sample 
            [@attr] => Array 
             (
              [alias] => three 
             ) 

           ) 

          [1] => Array // Would be renamed to "two" 
           (
            [user] => sample 
            [@attr] => Array 
             (
              [alias] => two 
             ) 

           ) 

         ) 

        [host] => test 
        [user] => test 
        [pass] => test 
        [name] => test 
        [port] => test 
        [@attr] => Array 
         (
          [alias] => development 
         ) 

       ) 

     ) 

这是到目前为止我的代码

private function _applyXmlAlias($array) 
     { 
      foreach ($array as $config) 
      { 
       if (is_array($config)) 
       { 
        if (isset($config['@attr']['alias'])) 
        { 
         $alias = $config['@attr']['alias']; 

         unset($config['@attr']['alias']); 

         if (empty($config['@attr'])) 
         { 
          unset($config['@attr']); 
         } 

         $this->_alias[$alias] = $config; 

         break; 

         //$this->_temp = reset(); 


        } else { 

         $this->_applyXmlAlias($config); 
        } 
       } 
      } 
     } 

如果我做我的_alias财产的print_r的我得到这个

Array 
(
    [production] => Array 
     (
      [host] => test 
      [user] => test 
      [pass] => test 
      [name] => test 
      [port] => 3306 
      [@attr] => Array 
       (
        [name] => live 
       ) 

     ) 

    [development] => Array 
     (
      [user_data] => Array 
       (
        [0] => Array 
         (
          [user] => sample 
          [@attr] => Array 
           (
            [alias] => three 
           ) 

         ) 

        [1] => Array 
         (
          [user] => sample 
          [@attr] => Array 
           (
            [alias] => two 
           ) 

         ) 

       ) 

      [host] => test 
      [user] => test 
      [pass] => test 
      [name] => test 
      [port] => 3306 
     ) 

) 

注:我不知道为什么只有我的循环使用密钥alias捕获最后一个嵌套数组,而不是其他具有值productiondevelopment

关于如何处理此问题的任何想法?我觉得我很接近,只需要一个正确的道路上的小指南。

感谢

编辑:更新我的功能,以反映当前attemps

+0

需要更多的休息...看到我下面的评论。 – EthanB

回答

0

你的算法是做了深度优先搜索。问题是它不知道何时终止。

相反void返回型,尝试这样的事情:

private function _applyXmlAlias($array) 
    { 
     $found_alias = FALSE; 
     foreach ($array as $config) 
     { 
      if (is_array($config)) 
      { 
       if (isset($config['@attr']['alias'])) 
       { 
        $this->_alias = reset(array_values($config)); 
        $found_alias = TRUE; 
         break; 
       } else { 
        if ($this->_applyXmlAlias($config)) { 
         $found_alias = TRUE; 
         break; 
        } 
       } 
      } 
     } 
     return $found_alias; 
    } 
+0

你会推荐什么?我应该在那里扔一个'break'吗?如果我尝试了类似的方法,但最终只能从其中一个键获取值。我已更新我的代码以显示我的最新尝试 – Eli

+0

更新了示例...中断不会完全解决它,您需要一种方法来告诉调用者(它是深度优先),您已找到某些内容并应该中断也是。 – EthanB

0

很有可能不是最完美的解决方案,但工程。

function renameArr($arr) { 
    foreach($arr as $key=>$val) { 
     if(is_array($val)) { 
      if(isset($val['@attr']['alias'])) { 
       unset($arr[$key]); 
       $key = $val['@attr']['alias']; 
      } 
      $arr[$key] = renameArr($val); 
     } 
    } 
    return $arr; 
}