PHP多维数组查找所有唯一路径

时间:2016-11-28 02:40:59

标签: php arrays multidimensional-array

我有一个PHP多维数组,每个节点都列出了它下面的父节点。我正在尝试转换数组,以便输出按层次结构列出,每个节点列出任何子节点,并且只列出数组中的唯一路径。

例如这个输入数组:

$input = [

        [
            "name" => "home",
            "parents" => [],
        ],
        [
            "name" => "newslist",
            "parents" => [
                [
                    "name" => "home",
                    "parents" => [],
                ],
            ],
        ],
        [
            "name" => "newsdetail",
            "parents" => [
                [
                    "name" => "newslist",
                    "parents" => [
                        [
                            "name" => "home",
                            "parents" => [],
                        ],
                    ],
                ],
                [
                    "name" => "home",
                    "parents" => [],
                ],
            ],
        ],
        [
            "name" => "knowledge",
            "parents" => [],
        ],
    ];

应该输出这个数组:

$output = [
        [
            "name" => "home",
            "children" => [
                [
                    "name" => "newslist",
                    "children" => [
                        [
                            "name" => "newsdetail",
                            "children" => [],
                        ],
                    ],
                ],
            ],
        ],
        [
            "name" => "knowledge",
            "children" => [],
        ],
    ];

1 个答案:

答案 0 :(得分:0)

这可能以更好的方式完成,但这种方法有效。只是程序功能作为概念证明。

<?php

$input = [

    [
        "name" => "home",
        "parents" => [],
    ],
    [
        "name" => "newslist",
        "parents" => [
            [
                "name" => "home",
                "parents" => [],
            ],
        ],
    ],
    [
        "name" => "newsdetail",
        "parents" => [
            [
                "name" => "newslist",
                "parents" => [
                    [
                        "name" => "home",
                        "parents" => [],
                    ],
                ],
            ],
            [
                "name" => "home",
                "parents" => [],
            ],
        ],
    ],
    [
        "name" => "knowledge",
        "parents" => [],
    ],
];

//recursively get all parents and the level the parent is at
function getParents($nodes,$level,&$parents)
{
    foreach($nodes AS $key => $node)
    {
        $parents[ $node['name'] ] = array( "name" => $node['name'], "level" => $level);
        if(isset($node['parents']) && !empty($node['parents']))
        {   
            $level += 1;
            getParents($node['parents'],$level,$parents);
        }
    }
}

//sort the parents by level
function sortParentsByLevel($a, $b) 
{
    if ($a['level'] == $b['level']) {
        return 0;
    }
    return ($a['level'] > $b['level']) ? -1 : 1;
}

//find the output path based on parents array to add new value to
function setValueFromPath(&$paths, $parents, $value)
{
    $dest = &$paths;

    if(empty($parents))
    {
        if(!isset($dest[$value]))
            $dest[$value] = array();

    } else {

        $finalNode = array_pop($parents);

        foreach ($parents as $parent) 
        {
            $dest = &$dest[$parent];
        }

        $dest[$finalNode][$value] = array();

    }

}

//init new variable
$output = array();

//loop through each input node
foreach($input AS $key => $node)
{    

    //init a parent array
    $parents = array();

    //if we have parents use the getParents method to set them
    if(isset($node['parents']) && is_array($node['parents']) && !empty($node['parents']))
    {
        getParents($node['parents'],1,$parents);
    }

    //sort the parents according to their level
    uasort($parents, 'sortParentsByLevel');

    //we're only interested in the associative key
    $parentKeys = array();
    foreach($parents AS $parent)
    {
        $parentKeys[] = $parent['name'];
    }

    //add the $node['name'] value in the appropriate parent array
    setValueFromPath($output, $parentKeys, $node['name'] );

}

echo '<pre>';
print_r($output);
echo '</pre>';
die();

/*
Array
(
    [home] => Array
        (
            [newslist] => Array
                (
                    [newsdetail] => Array
                        (
                        )

                )

        )

    [knowledge] => Array
        (
        )

)
*/