A recursive function to sort through parent and child nodes in PHP using a foreach loop on an array

前端 未结 2 1375
梦毁少年i
梦毁少年i 2021-01-07 10:18

I have a data set stored in an array that references itself with parent-child ids: id, parent_id, title etc. The top tier has a

2条回答
  •  不知归路
    2021-01-07 10:42

    I will try to help you.

    It is possible to compose such relations in one pass:

        /**
         * Used for "recursive" folding of layout items
         * Algorithm of infinite tree (non recursive method)
         * 
         * @param array $items
         * @return array
         */
        function _foldItems($items) {
    
            $result = array();
    
            foreach ($items as $key => $item) {
    
                $itemName = $item['name'];
    
                if (!isset($item['parent']))
                    continue;
                else {
    
                    $parentName = $item['parent']; // it can be either `name` or some `id` of the parent item
    
                    if (isset($result[$itemName][$item['sequence']])) {
    
                        // Done to eliminate `Warning: Cannot use a scalar value as an array in atLeisure_PropertyImport.class.php`
                        // Sometimes elements already in the list and have [name] => $count and next line tries to put item in array (item becomes parent)
                        if (    isset($result[$parentName][$item['parentSequence']]['items'][$itemName]) AND
                                is_scalar($result[$parentName][$item['parentSequence']]['items'][$itemName])
                            )
                            $result[$parentName][$item['parentSequence']]['items'][$itemName] = array();
    
                        $result[$parentName][$item['parentSequence']]['items'][$itemName][$item['sequence']] = $result[$itemName][$item['sequence']];
    
                        unset($result[$itemName][$item['sequence']]);
                    } else
                        $result[$parentName][$item['parentSequence']]['items'][$itemName] = $item['count'];
    
                    unset($items[$key]);
    
                    } // if //
    
                if (empty($result[$itemName]))
                    unset($result[$itemName]);
    
            } // foreach //
    
            foreach ($items as $item) { // enumerating rest of the items (single items)
                $itemName = $item['itemName'];
    
                if (!isset($result[$itemName]))
                    $result[$itemName][$item['sequence']] = $item['count'];
            }
    
            return $result;
    
        }
    

    Example can be a bit hard to read and to understand because there is really too much code, but I've made this function not so long ago for one project and it seems to be work successfully.

    NOTE: It will also work if there are several same items linked to one parent item. It uses item sequence number to avoid aliasing similar values into one.

提交回复
热议问题