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

时间:2019-12-26 19:29:15

标签: php arrays laravel

我坚持在第3个元素上分配pid(父代ID)。我的意思是在setParent()中,如果我在调用递归函数之前返回$array,那么我看到“ PC”和“ Laptop”具有正确的pid。 如果我运行所有脚本,那么我得到的$newArrnull。 PHP 7.3,Laravel 6。

我要这样做:

[
['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;
}

1 个答案:

答案 0 :(得分:1)

您可以使用implode为每个条目构建层次结构路径,然后使用array_reduce进行以下操作:

  • 通过条目的路径为您的条目编制索引,
  • 如果找到其后代的路径,则更改每个后续条目的pid

最后,array_values将把数组的索引切换回数字格式。

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

注释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);

演示:https://3v4l.org/DeORi