简体   繁体   English

PHP类别反向遍历算法

[英]PHP Category Reverse Traversal Algorithm

I'm trying to optimize an e-commerce category system with unlimited category depth (barring system memory limitations). 我正在尝试优化具有无限类别深度(除非存在系统内存限制)的电子商务类别系统。 I retrieve all the categories at once and order them as a multi-dimensional array that roughly looks like: 我立即检索所有类别,并将它们排序为大致如下所示的多维数组:

[array] (
  [0] (
    'CategoryId' => 1,
    'ParentCategoryId' => 0,
    'Title' => 'Category A',
    'SubCategories' => [array] (
      [0] (
        'CategoryId' => 2,
        'ParentCategoryId' => 1,
        'Title' => 'Category B',
        'SubCategories' => [array] (
          [0] (
            'CategoryId' => 3,
            'ParentCategoryId' => 2,
            'Title' => 'Category C'
          )
        )
      )
    )
  )
)

Each item in the array is actually an object, but for simplicity I wrote it out kind of like an array format. 数组中的每个项目实际上都是一个对象,但为简单起见,我将其写成类似于数组格式的形式。

I'm able to traverse my tree downwards using this function: 我可以使用此功能向下遍历我的树:

/**
* Find Branch using Recursive search by Object Key
* @param String     Needle
* @param Array      Haystack
* @return Array
*/
public static function findBranchByKey($key, $needle, $haystack)
{
    foreach ($haystack as $item) 
    {
        if ( $item->$key == $needle || ( is_object($item) && $item = self::findBranchByKey($key, $needle, $item->SubCategories)) ) 
        {
            return $item;
        }
    }
    return false;
}

This finds the object with a matching key and returns it (which may contain more subcategories). 这将找到具有匹配键的对象并将其返回(可能包含更多子类别)。

My issue is figuring out how to traverse the other direction. 我的问题是弄清楚如何穿越另一个方向。 For example, using the data above, let's say I am displaying "Category C" and want to create bread crumbs of it's parents. 例如,使用上面的数据,假设我正在显示“类别C”,并希望为其父母创建面包屑。 I can't think of a good way to take my tree array, jump to a specific subcategory, then iterate upwards to get each parent. 我想不出一个好方法来获取我的数组,跳转到特定的子类别,然后向上迭代以获取每个父级。 A resulting array from something like this could be like this so it's easy to spit them out as bread crumbs: 这样的结果数组可能是这样的,因此很容易将它们吐出面包屑:

 array( 'Category A', 'Category B', 'Category C' )

I could probably do this using SQL in my database but I'd like to retrieve the tree once, cache it, and perform traversal on that object whenever I need to rather than making tons of queries. 我可能可以在数据库中使用SQL进行此操作,但我想一次检索一次树,对其进行缓存,并在需要时对该对象执行遍历,而不是进行大量查询。

TL;DR; TL; DR; How can I traverse upwards in a multidimensional array of categories? 如何在多维类别的数组中向上遍历?

It can be done by recursion. 可以通过递归来完成。

Let's say, this function should work: 假设此功能应该起作用:

function getPath($id, $tree, &$path = array()) {
    foreach ($tree as $item) {
        if ($item['CategoryId'] == $id) {           
            array_push($path, $item['CategoryId']);
            return $path;
        }
        if (!empty($item['SubCategories'])) {
            array_push($path, $item['CategoryId']);
            if (getPath($id, $item['SubCategories'], $path) === false) {
                array_pop($path);
            } else {
                return $path;
            }

        }
    }
    return false;
}

This: 这个:

$data = array(
    array(
        'CategoryId' => 10,
        'ParentCategoryId' => 0,
        'SubCategories' => array(
            array(
                'CategoryId' => 12,
                'ParentCategoryId' => 1,
                'SubCategories' => array()
            ),
        )
    ),
    array(
        'CategoryId' => 1,
        'ParentCategoryId' => 0,
        'SubCategories' => array(
            array(
                'CategoryId' => 2,
                'ParentCategoryId' => 1,
                'SubCategories' => array()
            ),
            array(
                'CategoryId' => 3,
                'ParentCategoryId' => 1,
                'SubCategories' => array()
            ),
                        array(
                'CategoryId' => 4,
                'ParentCategoryId' => 1,
                'SubCategories' => array(
                    array(
                        'CategoryId' => 5,
                        'ParentCategoryId' => 4,
                        'SubCategories' => array()
                    ),
                )
            )
        )
    )
);

$result = getPath(5, $data);
print_r($result);

will result in: 将导致:

Array ( [0] => 1 [1] => 4 [2] => 5 )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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