首页 > 解决方案 > PHP Array:从 id 和 parent id 生成 id_path 和 level

问题描述

从这张表:
从这张表

我在 PHP 中得到了这个数组: array in PHP

我想向这个数组添加一个新行,我知道 category_id 和 parent_id,我如何编程 id_path 和 level ?

Edited1:例如最后一行:category_id:107,parent_id:106,如何编码 id_path=96/106/107 和级别?id_path:由斜线分隔的类别 ID 序列

编辑2:

    function test() {
        $arGiven = [ 
            [
                'category_id' => 100,
                'parent_id' => 107,
                'id_path' => '',
                'level' => 0,
            ],
            [
                'category_id' => 106,
                'parent_id' => 96,
                'id_path' => '',
                'level' => 0,
            ],
            [
                'category_id' => 107,
                'parent_id' => 106,
                'id_path' => '',
                'level' => 0,
            ]

        ];

        $arExpected = [ 
            [
                'category_id' => 100,
                'parent_id' => 107,
                'id_path' => '96/106/107/100',
                'level' => 4,
            ],
            [
                'category_id' => 106,
                'parent_id' => 96,
                'id_path' => '96/106',
                'level' => 2,
            ],
            [
                'category_id' => 107,
                'parent_id' => 106,
                'id_path' => '96/106/107',
                'level' => 3,
            ]

        ];

        $result = $arGiven;

        return $result;
    }

Edited3:我用这段代码试过了:

    function test() {
        $arGiven = [ 
            [
                'category_id' => 100,
                'parent_id' => 107,
                'id_path' => '',
                'level' => 0,
            ],
            [
                'category_id' => 106,
                'parent_id' => 96,
                'id_path' => '',
                'level' => 0,
            ],
            [
                'category_id' => 107,
                'parent_id' => 106,
                'id_path' => '',
                'level' => 0,
            ]

        ];

        $arExpected = [ 
            [
                'category_id' => 100,
                'parent_id' => 107,
                'id_path' => '96/106/107/100',
                'level' => 4,
            ],
            [
                'category_id' => 106,
                'parent_id' => 96,
                'id_path' => '96/106',
                'level' => 2,
            ],
            [
                'category_id' => 107,
                'parent_id' => 106,
                'id_path' => '96/106/107',
                'level' => 3,
            ]

        ];

        $arrays = $arGiven;

        function getParent($arr, $parent){
            foreach($arr as $v){
                if($v['parent_id'] == $parent) return $v['parent_id'];
            }
        
          return false;
        }

        $newArray=[];
        $i = 0;
        foreach ($arrays as $array){
            $newArray[] = $newArray[$i-1] . '/'. getParent($arrays, $array['parent_id']);
            $i++;
        }

        $test=1;
        return $array;
    }

但是 $newArray 是

[ 
  "/107",
  "/107/96",
  "/107/96/106"
]

代替:

[
    '96/106/107/100',
    '96/106',
    '96/106/107'
]

标签: phparraysrecursion

解决方案


我确信它可以真正优化:

<?php
    $arGiven = [ 
    // add the root category
        [
            'category_id' => 96,
            'parent_id' => 0,
            'id_path' => '',
            'level' => 0,
        ],
        [
            'category_id' => 100,
            'parent_id' => 107,
            'id_path' => '',
            'level' => 0,
        ],
        [
            'category_id' => 106,
            'parent_id' => 96,
            'id_path' => '',
            'level' => 0,
        ],
        [
            'category_id' => 107,
            'parent_id' => 106,
            'id_path' => '',
            'level' => 0,
        ]
    ];

    $level = 0;
    $parentLevelIds = [0];
    do {
        $level++;
        
        $nextParentLevelIds = [];
        $arGiven = array_map(function($value) use($level, $parentLevelIds, &$nextParentLevelIds, $arGiven) {
            if (in_array($value['parent_id'], $parentLevelIds)) {
                $path = '';
                if ($value['parent_id'] !== 0) {
                    $parent = array_filter($arGiven, function($parentSearchValue) use ($value) {
                        return $parentSearchValue['category_id'] == $value['parent_id'];
                    });
                    if (!empty($parent)) {
                        $path = array_shift($parent)['id_path'];
                    }
                }
                $value['level'] = $level;
                $value['id_path'] = empty($path) ? $value['category_id'] : ( $path . '/' . $value['category_id'] );
                $nextParentLevelIds[] = $value['category_id'];
            }
            return $value;
        }, $arGiven);

        $parentLevelIds = $nextParentLevelIds;

        $hasLevel0 = !empty(array_filter($arGiven, function($value) {
            return $value['level'] == 0;
        }));
    } while ($hasLevel0);

推荐阅读