1

無制限のカテゴリ深度 (システム メモリの制限を除く) で e コマース カテゴリ システムを最適化しようとしています。すべてのカテゴリを一度に取得し、大まかに次のような多次元配列として並べ替えます。

[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'
          )
        )
      )
    )
  )
)

配列内の各項目は実際にはオブジェクトですが、簡単にするために配列形式のように書きました。

この関数を使用して、ツリーを下にトラバースできます。

/**
* 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;
}

これにより、一致するキーを持つオブジェクトが検索され、それが返されます (さらにサブカテゴリが含まれる場合があります)。

私の問題は、他の方向にトラバースする方法を考え出すことです。例えば、上記のデータを使用して、「カテゴリ C」を表示していて、その親のパンくずリストを作成したいとします。ツリー配列を取得し、特定のサブカテゴリにジャンプしてから、上方向に反復して各親を取得する良い方法が思いつきません。このようなものから得られる配列は次のようになる可能性があるため、パンくずとして簡単に吐き出すことができます。

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

おそらくデータベースで SQL を使用してこれを行うことができますが、大量のクエリを作成するのではなく、必要なときにいつでもツリーを取得してキャッシュし、そのオブジェクトに対してトラバーサルを実行したいと考えています。

TL;DR; カテゴリの多次元配列を上に移動するにはどうすればよいですか?

4

1 に答える 1

1

それは再帰によって行うことができます。

たとえば、この関数は機能するはずです。

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;
}

これ:

$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);

結果は次のとおりです。

Array ( [0] => 1 [1] => 4 [2] => 5 )
于 2013-09-12T17:21:13.040 に答える