通过递归获取树

时间:2016-07-25 11:16:32

标签: laravel recursion

我有一个扁平数组,每个元素都包含一个'InstitutionId'和一个'ParentInstitutionId'。每个元素只有一个父元素,但可能有多个子元素。我知道它需要递归解决方案,我被困住了,无法找到出路。

Array
(
    [0] => Array
        (
            [InstitutionId] => 17507
            [InstitutionName] => abc
            [ParentInstitutionId] => 60936
        )

    [1] => Array
        (
            [InstitutionId] => 41679
            [InstitutionName] => abc
            [ParentInstitutionId] => 55701
        )

    [2] => Array
        (
            [InstitutionId] => 55701
            [InstitutionName] => abc
            [ParentInstitutionId] => 
        )

    [3] => Array
        (
            [InstitutionId] => 60936
            [InstitutionName] => abc 
            [ParentInstitutionId] => 128629
        )

    [4] => Array
        (
            [InstitutionId] => 71737
            [InstitutionName] => abc
            [ParentInstitutionId] => 17507
        )

)

我怎样才能把它变成一棵树,孩子们和那些孩子应该从根开始进入一个阵列。

2 个答案:

答案 0 :(得分:1)

由于你的标签包含Laravel,我会给你一个laravel解决方案:

    $collection = collect($yourArray)->keyBy('InstitutionId');
    $grouped = $collection->groupBy('ParentInstitutionId')
        ->map(function($children){
            return $children->keyBy('InstitutionId');
        })->all();
    $array = $collection->all();

    foreach ($array as $id => $item ){
        if (isset($grouped[$id]))
            $array[$id]['children'] = $grouped[$id];
    }

    foreach ($array as $id => $item ){
        if ($item['ParentInstitutionId']) {
            $parentId = $item['ParentInstitutionId'];
            $array[$parentId]['children'][$id] = $item;
        }
    }

    $tree = array_shift($array);

答案 1 :(得分:1)

您可以使用hasMany关系功能来实现这一目标。以下是您可以调整的一个示例:

1st - 使用您选择的重要名称在模型中声明您的关系。我们在这里说Tree模型(我们当前所在的文件)HAS MANY 对象(是的,本身有很多)。

2nd - 声明加载所有直接孩子的递归树。

树模型

class Tree extends Model {

    public function tree_immediate_children() {
        return $this->hasMany(Tree::class);
    }

    public function recursive_tree(){
        return $this->tree_immediate_children()->with('recursive_tree');
    }

}

3rd - 急切加载关系,然后仅由绝对父母过滤。这样你只能让孩子通过父母。

带着孩子回归树

return \App\Tree::with('recursive_tree')->get()->where('tree_id', null);

这是我用来实现上一代码的迁移。

移植

public function up() {
    Schema::create('trees', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->timestamps();
        $table->integer('tree_id')->unsigned()->nullable(true);
        $table->index(['tree_id']);
        $table->foreign('tree_id')->references('id')->on('trees')->onDelete('cascade');
    });
}

public function down() {
    Schema::drop('trees');
}

结果

{
  "trees": [
    {
      "id": 1,
      "name": "Lauriane Denesik",
      "created_at": "2016-07-25 13:55:34",
      "updated_at": "2016-07-25 13:55:34",
      "tree_id": null,
      "recursive_tree": [
        {
          "id": 4,
          "name": "Lea Terry",
          "created_at": "2016-07-25 13:55:39",
          "updated_at": "2016-07-25 13:55:39",
          "tree_id": 1,
          "recursive_tree": []
        },
        {
          "id": 5,
          "name": "Erna Jacobi",
          "created_at": "2016-07-25 13:55:39",
          "updated_at": "2016-07-25 13:55:39",
          "tree_id": 1,
          "recursive_tree": []
        },
        {
          "id": 6,
          "name": "Carmen Ferry",
          "created_at": "2016-07-25 13:55:39",
          "updated_at": "2016-07-25 13:55:39",
          "tree_id": 1,
          "recursive_tree": [
            {
              "id": 10,
              "name": "Alford Yost",
              "created_at": "2016-07-25 13:55:44",
              "updated_at": "2016-07-25 13:55:44",
              "tree_id": 6,
              "recursive_tree": []
            },
            {
              "id": 11,
              "name": "Eusebio Padberg",
              "created_at": "2016-07-25 13:55:44",
              "updated_at": "2016-07-25 13:55:44",
              "tree_id": 6,
              "recursive_tree": []
            },
            {
              "id": 12,
              "name": "Abdullah Wunsch",
              "created_at": "2016-07-25 13:55:44",
              "updated_at": "2016-07-25 13:55:44",
              "tree_id": 6,
              "recursive_tree": []
            }
          ]
        }
      ]
    },
    {
      "id": 2,
      "name": "Cruz Dickens",
      "created_at": "2016-07-25 13:55:34",
      "updated_at": "2016-07-25 13:55:34",
      "tree_id": null,
      "recursive_tree": [
        {
          "id": 7,
          "name": "Mr. Jesus Macejkovic DDS",
          "created_at": "2016-07-25 13:55:42",
          "updated_at": "2016-07-25 13:55:42",
          "tree_id": 2,
          "recursive_tree": []
        },
        {
          "id": 8,
          "name": "Tracy Jacobson PhD",
          "created_at": "2016-07-25 13:55:42",
          "updated_at": "2016-07-25 13:55:42",
          "tree_id": 2,
          "recursive_tree": []
        },
        {
          "id": 9,
          "name": "Prof. Uriel Goldner",
          "created_at": "2016-07-25 13:55:42",
          "updated_at": "2016-07-25 13:55:42",
          "tree_id": 2,
          "recursive_tree": []
        }
      ]
    },
    {
      "id": 3,
      "name": "Sabryna Torp",
      "created_at": "2016-07-25 13:55:34",
      "updated_at": "2016-07-25 13:55:34",
      "tree_id": null,
      "recursive_tree": []
    }
  ]
}
相关问题