如何递归地向每个数组添加键?

时间:2019-06-06 12:10:45

标签: php arrays recursion multidimensional-array

我有这个数组,

Array (
    [0] => Array (
        [P1] => Array (
            [P2] => Array (
                .
                    .
                        .
                            // n level
            ),
        ),
    ),
    [1] => Array (
        [P4] => Array (
            [P5] => Array (
                .
                    .
                        .
                            // n level
            ),
        ),
    ),
),

我想将其转换为该数组

Array (
    [0] => Array (
        'id' => 0
        [P1] => Array (
            'id' => 'P1',
            [P2] => Array (
                    'id' => 'P2'
                .
                    .
                        .
                            // n level
            ),
        ),
    ),
    [1] => Array (
        'id' => '1'
        [P4] => Array (
            'id' => 'P4'
            [P5] => Array (
                'id' => 'P5'
                .
                    .
                        .
                            n level
            ),
        ),
    ),
),

如您所见,我获取了每个键并将其映射到数组直接主体中的“ id”。

这是我尝试过的努力,

function recursive_function($arr)
{
    $result = [];
    if (is_array($arr)) {
        foreach ($arr as $el) {
            $result = array_merge($result, recursive_function($el));
        }
    } else {
        $result[] = $input;
    }
    return $result;
}

我是递归函数和php的新手,因此无法考虑如何以及在何处映射以及为什么。

请帮助我获得此输出。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:3)

这是一个很好的编程类家庭作业问题。在编写递归函数时,请先从结束执行的情况开始。因此,假设我有数组,并且想“修复”它:

$old; // This is my array;
$new = fix($old); // This takes my old array and gives me a fixed one.

基本情况是当我的数组为空时。如果是这种情况,我只将其退回,什么也不做。

function fix($a) {
  if(empty($a)) return $a;
}

如果不为空,则需要循环浏览各个元素。如果该元素不是数组,请不要对其执行任何操作。

function fix($a) {
  if(empty($a)) return $a;
  foreach($a as $i=>$v) {
    if(!is_array($v)) // do nothing
  }
}

所以,我只想在$ v是一个数组的情况下做些什么。我要怎么办我想向其中添加一个包含密钥(在我的代码中为$ i)的索引。

function fix($a) {
  if(empty($a)) return $a;
  foreach($a as $i=>$v) {
    if(is_array($v)) { // Only do something if $v is an array
      $a[$i]['id'] = $i;
    }
  }
}

快完成了。我们没有递归调用。因为$ v是一个数组,所以也需要修复。这很容易做到:

function fix($a) {
  if(empty($a)) return $a;
  foreach($a as $i=>$v) {
    if(is_array($v)) { // Only do something if $v is an array
      $a[$i] = fix($v);
      $a[$i]['id'] = $i;
    }
  }
}

现在,$ v将被修复并替换其在数组中的旧self。然后,将添加id索引。但是,有一些重要的事情要做。我们需要返回固定数组!

function fix($a) {
  if(empty($a)) return $a;
  foreach($a as $i=>$v) {
    if(is_array($v)) { // Only do something if $v is an array
      $a[$i] = fix($v);
      $a[$i]['id'] = $i;
    }
  }
  return $a;
}

答案 1 :(得分:1)

@kainaw的答案很好,但这只是递归解决方案的简单版本:

function addId(&$arr) {
    foreach($arr as $k => &$v) {
        addId($v);
        $v = array_merge(["id" => $k], $v);
    }
}
$arr = [["P1" => ["P2" => []]], ["P4" => ["P5" => []]]];
addId($arr);

请注意&,它使用数据作为参考,因此原始数组正在更改