我有一个多维数组,如下所示:
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
格式。树标签是固定的。没有比上面代码中显示的更深或更少的深度。
最好的方法是什么?感谢您的帮助
答案 0 :(得分:0)
试试这个:
$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]);
}
}
}
}
我认为这可以给你一些想法,但我没有测试过,所以我不确定正确性。
答案 1 :(得分:0)
不需要疯狂的嵌套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);
答案 2 :(得分:0)
你可以像你问的那样:遍历和更改密钥(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
内部需要检查是否已经处理了一个密钥(它是一个新密钥,所有新密钥都是字符串)。