Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/245.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP为数组中的子项分配父ID_Php_Arrays_Laravel - Fatal编程技术网

PHP为数组中的子项分配父ID

PHP为数组中的子项分配父ID,php,arrays,laravel,Php,Arrays,Laravel,我一直在第三个元素上分配pid的父id。我的意思是在setParent中,如果我在调用递归函数之前返回$array,那么我会看到PC和笔记本电脑都有正确的pid。 若我运行所有脚本,那个么$newArr为空。PHP7.3,Laravel6 我想说: [ ['pc', ['pc',null, null] ,'id'=>1,'pid'=>1], ['laptop', ['pc','laptop', null] ,'id'=>2

我一直在第三个元素上分配pid的父id。我的意思是在setParent中,如果我在调用递归函数之前返回$array,那么我会看到PC和笔记本电脑都有正确的pid。 若我运行所有脚本,那个么$newArr为空。PHP7.3,Laravel6

我想说:

[
['pc',         ['pc',null,     null]       ,'id'=>1,'pid'=>1],
['laptop',     ['pc','laptop', null]       ,'id'=>2,'pid'=>1],
['acc',        ['pc','acc',    null]       ,'id'=>3,'pid'=>1],
['bags',       ['pc','acc',   'bags']      ,'id'=>4,'pid'=>3],
['adapter',    ['pc','acc',   'adapter']   ,'id'=>5,'pid'=>3],
['clothes',    ['clothes',null,null]       ,'id'=>6,'pid'=>6]
];
由此:

function test3(){
    $array = [
        ['pc',         ['pc',null,     null]       ,'id'=>1,'pid'=>0],
        ['laptop',     ['pc','laptop', null]       ,'id'=>2,'pid'=>0],
        ['acc',        ['pc','acc',    null]       ,'id'=>3,'pid'=>0],
        ['bags',       ['pc','acc',   'bags']      ,'id'=>4,'pid'=>0],
        ['adapter',    ['pc','acc',   'adapter']   ,'id'=>5,'pid'=>0],
        ['clothes',    ['clothes',null,null]       ,'id'=>6,'pid'=>0]
    ];
    $newArr = $this->setParent($array);
    return  response()->json([$newArr]);
}

function setParent($array, $goStop='go'){
    if($goStop == 'go'){
        $foundPids = 0;
        foreach($array as $k => $v){
            if( $v["pid"] == 0) $foundPids++;
        }
        if( $foundPids == 0){
            return $this->setParent($array, 'stop'); // or return $array;
        }

        // parent search
        foreach($array as $k1 => $v1){
            if ($v1['pid']!=0)
                break;

            $keyInd = array_search($v1[0] , $v1[1]);// $v1 looks like {"0":"pc","1":["pc",null,null],"id":1,"pid":0}

            if($keyInd == 0){
                $array[$k1]['pid'] = $v1['id']; // PC updated
            }

            if($keyInd > 0){
                $parentName = $v1[1][$keyInd-1];
                $IdToWriteInPid = 0;
                foreach ($array as $k1inner => $v1inner){
                    if($v1inner[$keyInd-1] == $parentName){
                        $IdToWriteInPid = $v1inner['id'];
                    }
                }

                $array[$k1]['pid'] = $IdToWriteInPid; // Laptop updated
                //
                // if uncomment, then i see that category PC having pid 1
                // and category Laptop having pid 1. It is ok.
                //
                // return $array;
                //

                return $this->setParent($array, 'go' );
            }
        }
    }
    else return $array;
}

您可以使用为每个条目构建层次结构路径,然后使用:

按路径为条目编制索引, 如果找到每个后续条目的父项路径,则更改其pid。 最后,将把数组的索引切换回数字格式

注意:这假设父对象总是在其子对象之前定义,就像在示例数据中一样

注2:这还假设“pc”等名称不能包含正斜杠/。否则,请随意更换分离器

function fillParentIds(array $input): array
{
  return array_values(array_reduce($input, static function (array $entriesByPath, array $entry): array {
    $hierarchy = array_filter($entry[1]);
    $pathToParent = implode('/', array_slice($hierarchy, 0, -1));
    $pathToEntry = implode('/', $hierarchy);

    $entry['pid'] = array_key_exists($pathToParent, $entriesByPath) 
      ? $entriesByPath[$pathToParent]['id'] 
      : $entry['id'];

    $entriesByPath[$pathToEntry] = $entry;
    return $entriesByPath;
  }, []));
}
用法:

$withParentIds = fillParentIds($input);

演示:

条目是否可以在其后面定义其父项?换句话说,起始输入数组的顺序是相反的吗?@Jeto实际上不是。我需要导入Excell,其中有3列可以在内部数组中看到。