如何在PHP中修复递归?

时间:2017-05-30 07:11:28

标签: php recursion

我尝试在递归

中迭代所有父母/孩子
foreach ($data as $k => $item) {
   $data[$k]["children"] = $this->getChildren($all, $item);
}

递归函数

 private function getChildren($list, $item)
    {
        $children = [];

        if (is_array($item["children"])) {

            foreach ($item["children"] as $k => $id) {
                $children[] = $list[$id];
            }

        } else {

            if (isset($list[$item["children"]])) {
                $children[] = $list[$item["children"]];
            }
        }

        return $children;
    }

问题是我需要在getChildren内为已创建元素getChildren调用$list[$id]来检查此元素是否包含数组

我试着称之为:

$children[] = $this->getChildren($list, $list[$id]);

但它不起作用。

我试过这种方式:

private function getChildren($list, $item)
    {
        $children = [];

        if (is_array($item["children"]) && count($item["children"]) > 0) {

            foreach ($item["children"] as $k => $id) {
                return $this->getChildren($list, $list[$id]);
            }
        }

        return $list[$id];
    }

我尝试按$all迭代的数组children

array:12 [
  "592d0b3bb3569e257208db81" => array:10 [
    "_id" => MongoId {#266
      +$id: "592d0b3bb3569e257208db81"
    }
    "name" => "Характеристики героя"
    "default" => "data"
    "visibility" => null
    "type" => "2"
    "value" => "data"
    "prefix" => "data"
    "type_value" => "object"
    "children" => array:7 [
      0 => "592d094eb3569eb07208db7e"
      1 => "592d0961b3569ee17708db80"
      2 => "592d0978b3569eb07108db7e"
      3 => "592d0987b3569ead7108db91"
      4 => "592d09a5b3569eae7108db81"
      5 => "592d09c1b3569eae7208db82"
      6 => "592d0ac3b3569eae7208db83"
    ]
    "available" => "1"
  ]
  "592d0ac3b3569eae7208db83" => array:10 [
    "_id" => MongoId {#267
      +$id: "592d0ac3b3569eae7208db83"
    }
    "name" => "Умения"
    "default" => "skills"
    "visibility" => null
    "type" => "2"
    "value" => "skills"
    "prefix" => "skills"
    "type_value" => "object"
    "children" => array:4 [
      0 => "592d094eb3569eb07208db7e"
      1 => "592d0a1db3569ee17708db81"
      2 => "592d0a2fb3569e257208db80"
      3 => "592d0a58b3569ead7108db92"
    ]
    "available" => "1"
  ]
  "592d0a58b3569ead7108db92" => array:10 [
    "_id" => MongoId {#268
      +$id: "592d0a58b3569ead7108db92"
    }
    "name" => "Начальная прокачка"
    "default" => "0"
    "visibility" => null
    "type" => "1"
    "value" => "0"
    "prefix" => "startPumping"
    "type_value" => "integer"
    "children" => []
    "available" => "1"
  ]
  "592d0a2fb3569e257208db80" => array:10 [
    "_id" => MongoId {#269
      +$id: "592d0a2fb3569e257208db80"
    }
    "name" => "Максимальная прокачка"
    "default" => "0"
    "visibility" => null
    "type" => "1"
    "value" => "0"
    "prefix" => "maxPumping"
    "type_value" => "integer"
    "children" => []
    "available" => "1"
  ]
  "592d0a1db3569ee17708db81" => array:10 [
    "_id" => MongoId {#270
      +$id: "592d0a1db3569ee17708db81"
    }
    "name" => "Текущая прокачка"
    "default" => "0"
    "visibility" => null
    "type" => "1"
    "value" => "0"
    "prefix" => "pumping"
    "type_value" => "integer"
    "children" => []
    "available" => "1"
  ]
  "592d09c1b3569eae7208db82" => array:10 [
    "_id" => MongoId {#271
      +$id: "592d09c1b3569eae7208db82"
    }
    "name" => "Свободных умений"
    "default" => "0"
    "visibility" => null
    "type" => "1"
    "value" => "0"
    "prefix" => "freePumpingPoints"
    "type_value" => "integer"
    "children" => []
    "available" => "1"
  ]
  "592d09a5b3569eae7108db81" => array:10 [
    "_id" => MongoId {#272
      +$id: "592d09a5b3569eae7108db81"
    }
    "name" => "Требования"
    "default" => "Что бы получить Этого персонажа, вам нужно заплатить миллион американских рублей и подарить нам почку"
    "visibility" => null
    "type" => "1"
    "value" => "Что бы получить Этого персонажа, вам нужно заплатить миллион американских рублей и подарить нам почку"
    "prefix" => "requirements"
    "type_value" => "string"
    "children" => []
    "available" => "1"
  ]
  "592d0987b3569ead7108db91" => array:10 [
    "_id" => MongoId {#273
      +$id: "592d0987b3569ead7108db91"
    }
    "name" => "Описание"
    "default" => "Описание"
    "visibility" => null
    "type" => "1"
    "value" => "Описание"
    "prefix" => "description"
    "type_value" => "string"
    "children" => []
    "available" => "1"
  ]
  "592d0978b3569eb07108db7e" => array:10 [
    "_id" => MongoId {#274
      +$id: "592d0978b3569eb07108db7e"
    }
    "name" => "Название"
    "default" => "Название"
    "visibility" => null
    "type" => "1"
    "value" => "Название"
    "prefix" => "name"
    "type_value" => "string"
    "children" => []
    "available" => "1"
  ]
  "592d0961b3569ee17708db80" => array:10 [
    "_id" => MongoId {#275
      +$id: "592d0961b3569ee17708db80"
    }
    "name" => "Уровень"
    "default" => "0"
    "visibility" => null
    "type" => "1"
    "value" => "0"
    "prefix" => "level"
    "type_value" => "integer"
    "children" => []
    "available" => "1"
  ]
  "592d094eb3569eb07208db7e" => array:10 [
    "_id" => MongoId {#276
      +$id: "592d094eb3569eb07208db7e"
    }
    "name" => "Идентификатор"
    "default" => "0"
    "visibility" => null
    "type" => "1"
    "value" => "0"
    "prefix" => "id"
    "type_value" => "integer"
    "children" => []
    "available" => "1"
  ]
  "592d0932b3569e277208db87" => array:10 [
    "_id" => MongoId {#277
      +$id: "592d0932b3569e277208db87"
    }
    "name" => "Сила отбития"
    "default" => "0"
    "visibility" => null
    "type" => "1"
    "value" => "0"
    "prefix" => "hitForce"
    "type_value" => "integer"
    "children" => []
    "available" => "1"
  ]
]"available" => "1"
  ]
]

我的递归版本:

private function getChildren($list, $item, $c)
    {

        if (is_array($item["children"])) {

            foreach ($item["children"] as $k => $id) {


                if(count($list[$id]["children"]) > 0){

                    $_id = (string)$list[$id]["_id"];

                    $c[][$_id] = $list[$id];
                    $c[][$_id]["children"] = $this->getChildren($list, $list[$id], $c);

                } else {

                    $c[] = $list[$id];
                }
            }
        }

        return $c;
    }

调用

 foreach ($data as $k => $item) {

            $data[$k]["children"] = $this->getChildren($all, $item, $c);
        }

1 个答案:

答案 0 :(得分:1)

这是一个使用采样器数组而不是数组的快速示例,只是为了在一般情况下澄清和简化解决方案。

$data = [
    0 => ['name' => 'b0', 'children' => [3,5]],
    1 => ['name' => 'b1', 'children' => []],
    2 => ['name' => 'b2', 'children' => [1]],
    3 => ['name' => 'b3', 'children' => []],
    4 => ['name' => 'b4', 'children' => []],
    5 => ['name' => 'b5', 'children' => [4]],
];

function recursive($data, $childs)
{
    $list = [];
    foreach ($childs as $child) {
        if (is_array($data[$child]['children'])) {

            // storing the output of the recursive array in a tmp variable
            $tmpArray['name'] = $data[$child]['name'];
            $tmpArray['children'] = recursive($data, $data[$child]['children']);
        } else {
            $tmpArray = $data[$child];
        }
        $list[] = $tmpArray;
    }

    return $list;
}

foreach ($data as $key => $value) {

    // Here we are going to check whether the array have inner childs or not , only to take in account the other empty elements

    if (is_array($value['children']) && count($value['children']) > 0) {
        $list[] = recursive($data, $value['children']);
    } else {
        $list[] = $value;
    }
}

print_r($list);

这是一个快速演示:https://eval.in/807433

P.S ,您获得的数据越多,负载和数据量就越大。你得到的时间

也许重新设计你的mongoDB文件是避免这种情况的好选择,也许