我有一个多维数组,看起来像这样:
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
中,如果一个键已经被处理(它是一个新键,所有新键都是字符串),则需要进行检查以退出。