Category hierarchy from array(cat id => parent id)

后端 未结 6 1946
你的背包
你的背包 2021-01-24 23:26

i am trying to create a multidimensional array hierarchy from a simple array which contains pairs of category ids and parent ids. The categories can be a parent and a subcategor

相关标签:
6条回答
  • 2021-01-24 23:33

    Is there any way you can change the way that the array is generated? As you have it now, will be more hassle then it's worth to try and generate what you want.

    Alternatively, you could try and generate something like this:

    $menu = array(
        0 => array(0, 1, 2, 3),
        1 => array(0, 1),
    );
    

    Allowing a simple loop like this:

    <ul>
        <?php foreach ($menu as $parent => $subs) : ?>
            <li>
                <?php echo $parent; ?>
                <ul>
                    <?php foreach ($subs as $index => $val): ?>
                        <li>
                            <?php echo $val; ?>
                        </li>
                    <?php endforeach; ?>
                </ul>
            </li>
    
        <?php endforeach; ?>
    </ul>
    

    The above is templating syntax, I'm sure we all know what this is so I'm now going to explain it.

    Or the simple loop would look like this:

    echo "<ul>";
    foreach($menu as $parent => $subs){
        echo "<li>";
        echo $parent;
        echo "<ul>";
        foreach($subs as $index => $val) {
            echo "<li>";
            echo $val;
            echo "</li>";
        }
        echo "</ul>";
        echo "</li>";
    }
    echo "</ul>";
    
    0 讨论(0)
  • 2021-01-24 23:37

    Well it appears to me you need a recursive function. Assuming everything has a parent or value beginning at the base level of 0, I resituated the array to have all parent ids listing their children rather than the other way around above. After that, I created a recursive function.

    $initialArray = array(
        1 => 0,
        2 => 1,
        3 => 2,
    
        4 => 0,
        5 => 4,
    
        6 => 0
    );
    
    // resituate the array
    $parent_ids = array();
    foreach ($initialArray as $category_id => $parent_id) {
        if (!isSet($parent_ids[$parent_id])) {
            $parent_ids[$parent_id] = array();
        }
        $parent_ids[$parent_id][] = $category_id;
    }
    
    // end_array is the result
    $end_array = array();
    
    /**
     * Takes the key of the parent, the current set that it's working off of, the list of parent ids for reference
     * and the current place in the end result array, acting recursively
     */
    function recursive($parent_key, $current_set, $parent_ids, $end_array) {
        foreach ($current_set as $parent_value) {
            if (!isSet($parent_ids[$parent_value])) {
                $end_array[$parent_key][] = $parent_value;
            } else {
                // if the parent_value is found in parent_ids, pass those values to the same function and the current end_array position
                $end_array[$parent_key] = recursive($parent_value, $parent_ids[$parent_value], $parent_ids, $end_array[$parent_key]);
            }
        }
        return $end_array;
    }
    // start with the top most element
    $end_array = recursive(key($parent_ids), current($parent_ids), $parent_ids, $end_array);
    
    print '<pre>'.
        print_r($parent_ids, true).
        print_r($end_array,true).
        '</pre>'
    ;
    

    Outputs:

    // resituated array
    Array
    (
        [0] => Array
            (
                [0] => 1
                [1] => 4
                [2] => 6
            )
    
        [1] => Array
            (
                [0] => 2
            )
    
        [2] => Array
            (
                [0] => 3
            )
    
        [4] => Array
            (
                [0] => 5
            )
    
    )
    
    // the end result
    Array
    (
        [0] => Array
            (
                [1] => Array
                    (
                        [2] => Array
                            (
                                [0] => 3
                            )
    
                    )
    
                [4] => Array
                    (
                        [0] => 5
                    )
    
                [5] => 6
            )
    
    )
    
    0 讨论(0)
  • 2021-01-24 23:41

    I know, late to the party but it looks interesting...

    /*
     * This is a 'multiway' tree where:
     *   a 'parent' can have any number of 'child' nodes
     *   therefore the 'parent node' must look like:
     *   [parentId] => array()
     *
     *   where [parentId] is the index of an array;
     */
    

    It will insert one node at a time starting from the root node. It can get very expensive for large trees.

    Working example at: Viper-7.com

    The routine that does the work:

    /**
     * Insert:  Find the 'parent' node
     *          if child not found then insert a 'node'
     *
     * @param array node passed by reference as the new node will be inserted
     * @param integer $parentId - root Id must be the lowest value
     * @param integer $childId
     * @return boolean  true if parentId found and processed
     */
    function insertNode(&$node, $parentId, $childId) {
    
        if (isset($node[$parentId])) { // this node will be processed
            if (!isset($node[$parentId][$childId])) {
                $node[$parentId][$childId] = array(); // add child node
                return true;
            }
            return true; // end of processing
        }
    
        // check all the children of this node...
        foreach($node as &$child) { // need the reference
            if (insertNode($child, $parentId, $childId)) {
                return true;
            }
        }
        return false; // parentId not in the tree
    }
    

    Notes:

    The node to be processed is passed by reference.
    The processing will end when the 'parent' id is found 
    

    The input node list as given is 'child' => 'parent' order which is unusual, it is ok, just remember that in the processing...

    Process the input data:

    $theTree = array(current($links) => array()); // root
    
    // insert all the child nodes into the tree
    foreach($links as $childId => $parentId) {
        $inserted = insertNode($theTree, $parentId, $childId);
    }
    
    // output the tree
    echo '<pre>', 'Children are in the same order as the input array.', '<br />';
        print_r($theTree);
    echo '</pre>';
    

    The input list needs to be arraged so that the 'tree' will be loaded such that the parent of the child to be added must be in the tree already. i assume that the input list is in the required order already

    Test data, sort and display:

    # cat_id => parent_id
    $links = array(
       1 => 0,
       2 => 1,
       3 => 2,
    
       4 => 0,
       5 => 4, // multiple children
      11 => 4,
      99 => 4,
      13 => 11,
    
       6 => 0
    );
    

    Output, i added a sub-tree to the original input...

    Children are in the same order as the input array.
    Array
    (
        [0] => Array
            (
                [1] => Array
                    (
                        [2] => Array
                            (
                                [3] => Array
                                    (
                                    )
                            )
                    )
                [4] => Array
                    (
                        [5] => Array
                            (
                            )
    
                        [11] => Array
                            (
                                [13] => Array
                                    (
                                    )
                            )
                        [99] => Array
                            (
                            )
                    )
                [6] => Array
                    (
                    )
            )
      )
    
    0 讨论(0)
  • 2021-01-24 23:44

    Get your list :

    <?php 
    $initialArray = array(
      1 => 0,
      2 => 1,
      3 => 2,
      4 => 0,
      5 => 4,
      6 => 0
    );
    
    
    $menus = array();
    
    function generateMenus($start) {
        global $initialArray;
        foreach($initialArray as $k => $v) {
           if($start == $v) {
              $menus[] = $k;
           }
        }
        return $menus;
    }
    $final = array();
    foreach($initialArray as $key => $value) {
       $final[$value] = generateMenus($value);
    }
    
    echo '<ul>';
    function generateList($start) {
        global $final;
        echo '<li>'.$start.'</li>';
        if(!empty($final[$start])) {
            echo '<ul>';
            foreach($final[$start] as $v) {
                generateList($v);
            }
            echo '</ul>';
        }
    }
    generateList(0);
    echo '</ul>';
    
    
    ?>
    

    It will produce

    0 讨论(0)
  • 2021-01-24 23:48

    If you want to form a recursive array you can refer on this page

    Recursive function to generate multidimensional array from database result

    this may help you a lot. Thanks.

    0 讨论(0)
  • 2021-01-24 23:55

    You can make an array like this

    $initialArray = array();
    $initialArray[parent_id][cat_id]='your_value';   //$initialArray[0][0] ... and then increasing
    
    0 讨论(0)
提交回复
热议问题