横穿&;在多维php数组中更改子键

横穿&;在多维php数组中更改子键,php,arrays,multidimensional-array,Php,Arrays,Multidimensional Array,我有一个多维数组,如下所示: Array( [135] => Array( [150] => Array( [151] => Array( [1] => Array() [153] => Array() ) [1] => Array( [1] => Array() [2] => Array() ) ) [1

我有一个多维数组,如下所示:

Array(
  [135] => Array(
    [150] => Array(
      [151] => Array(
        [1]   => Array()
        [153] => Array()
      )
      [1] => Array(
        [1] => Array()
        [2] => Array()
      )
    )
    [1] => Array(
      [1] => Array(
        [1] => Array()
        [2] => Array()
      )
      [2] => Array(
        [1] => Array()
        [2] => Array()
      )
    )
  )
)
我想改为:

Array(
  [135] => Array(
    [150|135] => Array(
      [151|150] => Array(
        [1|151]   => Array()
        [153|151] => Array()
      )
      [1|150] => Array(
        [1|1] => Array()
        [2|1] => Array()
      )
    )
    [1|135] => Array(
      [1|1] => Array(
        [1|1] => Array()
        [2|1] => Array()
      )
      [2|1] => Array(
        [1|2] => Array()
        [2|2] => Array()
      )
    )
  )
)
我的意思是每个子密钥都将具有
他的密钥|父密钥
格式。树标签是固定的。深度不大于或小于上述代码中所示的深度

最好的方法是什么?感谢您的帮助

试试这个:

    $arr = Array ( [135] => Array ( [150] => Array ( [151] => Array ( [1] => Array ( )))));

foreach($arr as $key1 => $value1)
{
    if(is_array($value1))
    {
        foreach($value1 as $key2 => $value2)
        {
            if(is_array($value2))
            {
                  foreach($value2 as $key3 => $value3)
                  {
                      if(is_array($value3))
                      {
                          foreach($value3 as $key4 => $value4)
                          {
                              if(is_array($value4))
                              {
                                   foreach($value4 as $key5 => $value5)
                                   {
                                        $value4[$key5.'|'.$key4] = $value5;
                                        unset($value4[$key5]);
                                   }
                              }
                              else
                              {
                                   $value3[$key4.'|'.$key3] = $value4;
                                   unset($value3[$key4]);
                              }
                          }                          
                       }
                       else
                       {
                           $value2[$key3.'|'.$key2] = $value3;
                           unset($value2[$key3]);
                       }
                  }
            }
            else
            {
                 $value1[$key2.'|'.$key1] = $value2;
                 unset($value1[$key2]);
            }
        }
    }
}

我想这可以给你一些想法,但我还没有测试过,所以我对正确性不是很确定。

没有必要用疯狂的嵌套
foreach()
循环来解决这个问题。递归是您的朋友:

function get_fancy_array($arr, $parent_id=null) {
  $fancy_arr = array();

  // turn e.g. 'parent' or 'parent|child' into '|parent' and NULL into ''
  $parent_id_sufx = $parent_id === null ?
    '' : '|' . explode('|', (strint)$parent_id, 1)[0];

  foreach($arr as $key => $val) {
    $key = (string)$key . $parent_id_sufx;

    if( is_array($val) ) {
      // it's an array, so recursively do the same thing at the next level
      $fancy_array[$key] = get_fancy_arr($val, $key);
    } else {
      $fancy_array[$key] = $val;
    }
  }

  return $fancy_arr;
}

// Usage:
$arr = array( /* your big nested array here */ );

$fancier_arr = get_fancy_array($arr);
print_r($fancier_arr);

您可以完全按照要求执行:遍历和更改键():

此函数使用递归进行遍历(函数本身调用),因此它可以在多个级别上进行操作

更改数组键实际上是不可能的,没有像
array\u rename\u key
这样的功能。而是添加具有新密钥的项,然后删除具有旧密钥的项。为了不复制值,在上面的示例中使用了一个引用/别名:

$a["$k|$p"] = &$v;            
unset($a[$k]);
$a
是数组,
$v
是当前元素的值,
$k
是键,
$p
是父元素的键


当在数组末尾添加新元素时,在
foreach
中,需要检查是否已处理某个键(它是新键,所有新键都是字符串)。

您需要使用字符串键,而不是数字键。你想让递归函数从一种格式转换到另一种格式吗?这可以通过字符串键控字典或对象来实现,但最终只是一个双链接树。谢谢hakre。这对我很有帮助
$a["$k|$p"] = &$v;            
unset($a[$k]);