遍历和更改多维 php 数组中的子键



我有一个多维数组,看起来像这样:

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()
      )
    )
  )
)

我的意思是每个子键将具有his key | parent key格式。树标签是固定的。不超过或少于上面代码中显示的深度。

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

试试这个:

    $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);

你完全可以做到你所要求的:遍历和更改键(Demo):

/**
 * traverse array and
 * add parent key to children key
 * 
 * @param array $a (return)
 * @param int $p (optional) parent key 
 */
function changeKeys(array &$a, $p = null)
{
    static $f = __FUNCTION__;
    foreach($a as $k => &$v)
    {
        # test if already processed
        if (is_string($k))
            return;
        # traverse children if children exists
        if ($v)
            $f($v, $k);        
        # rename key if parent exists
        if ($p)
        {
            $a["$k|$p"] = &$v;            
            unset($a[$k]);
        }
    }
}

此函数使用递归遍历(函数调用自身),因此可以在相同的多个级别上操作。

改变数组键实际上是不可能的,没有像array_rename_key这样的功能。相反,添加带有新键的项,然后删除带有旧键的项。为了不重复值,在上面的例子中使用了引用/别名:

$a["$k|$p"] = &$v;            
unset($a[$k]);

$a为数组,$v为当前元素的值,$k为键,$p为父元素的键。

当在数组末尾添加新元素时,在foreach中,如果一个键已经被处理(它是一个新键,所有新键都是字符串),则需要进行检查以退出。

相关内容

  • 没有找到相关文章

最新更新