简体   繁体   中英

Re-structure n-level array with parent/child relation (PHP)

I want to restructure an array and some of the solutions on stuckoverflow helped me to make it "proper" for the 1-st level items, but you'll notice the array is n-level deep.

The method restructure() is not used recursively (it should be). It's probably wrong alltogether, and have no idea how to make it right.

The children key says there are children with the respective id's, parent key links the item to the parent id.

class FilterMenu {

    protected $tree = array();

    static protected $structure = array();

    public function __construct(array $tree)
    {
        $this->tree = $tree;
    }

    public function getStructure()
    {
        self::restructure($this->tree);
        return self::$structure;
    }

    static public function restructure(array $structure)
    {
        foreach ($structure as $k => $v)
        {
            if (isset($v['parent']) and isset($v['children']) and count($v['children']) == 1)
            {
                // only 1 child
                self::$structure[$k] = current(array_keys($v['children']));
            }
            elseif (isset($v['children']))
            {
                $keys = array_keys($v['children']);
                self::$structure[$k] = array_combine($keys, $keys); // mirror array

                //self::restructure($v['children']);
            }
            else
            {
                // no children
                self::$structure[$k] = $k;
            }
        }
    }
}



// test array

$tree = array(
    1 => array(
        'parent' => 1
    ),
    2 => array(
        'parent' => 2,
        'children' => array(
            3 => array(
                'parent' => 2
            ),
            6 => array(
                'parent' => 2,
                'children' => array(
                    10 => array(
                        'parent' => 6,
                        'children' => array(
                            4 => array(
                                'parent' => 10
                            )
                        )
                    )
                ),
            ),
        ),
    ),
    7 => array(
        'parent' => 7,
        'children' => array(
            11 => array(
                'parent' => 7
            )
        )
    ),
    14 => array(
        'parent' => 14,
        'children' => array(
            15 => array(
                'parent' => 14,
            ),
            16 => array(
                'parent' => 14,
            ),
            19 => array(
                'parent' => 14,
            ),
            20 => array(
                'parent' => 14,
            ),
            21 => array(
                'parent' => 14,
            ),
        )
    )
);

// test:
$tree = new FilterMenu($tree);
echo '<pre>'.print_r($tree->getStructure(), true);

Actual result:

Array
(
    [1] => 1
    [2] => Array
        (
            [3] => 3
            [6] => 6
        )

    [7] => 11
    [14] => Array
        (
            [15] => 15
            [16] => 16
            [19] => 19
            [20] => 20
            [21] => 21
        )

)

the desired/expected result is:

Array
(
    [1] => 1
    [2] => Array
        (
            [3] => 3
            [6] => Array
                (
                    [10] => 4 // <-- array with n-levels...
                )

        )

    [7] => 11
    [14] => Array
        (
            [15] => 15
            [16] => 16
            [19] => 19
            [20] => 20
            [21] => 21
        )

)

Here is the link to codepad that tests the class and the array.

Any help is greatly appreciated. Thanks.

I think you are looking for this:

function collapse(&$array) {
  foreach ($array as $k => &$v) {
    if (array_key_exists('children', $v)) {
      collapse($v['children']);
      $array[$k] = $v['children'];
    } else {
      $array[$k] = $k;
    }
  }
}

which, when called like this:

collapse($tree);
print_r($tree);

produces:

Array (
  [1]  => 1
  [2]  => Array (
            [3] => 3
            [6] => Array (
                     [10] => Array (
                               [4] => 4
                             )
                   )
          )
  [7]  => Array (
            [11] => 11
          )
  [14] => Array (
            [15] => 15
            [16] => 16
            [19] => 19
            [20] => 20
            [21] => 21
         )
)

See http://codepad.org/8atfSWGC

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM