PHP Многомерный массив с идентификатором родителя для массива таксономии категории, стиль Ebay


Иду уже несколько дней, готов бросить курить. Я звоню в торговый API eBay, чтобы вернуть список категорий. В приведенном ниже массиве показано, как эти категории возвращаются из API. Я изо всех сил пытаюсь упорядочить это в таксономию, подобную первому серому прямоугольнику ниже.

Обратите внимание, что число в начале каждой строки является идентификатором конечной категории для этой конкретной строки.

3270: Vehicle Electronics & GPS
175716: Vehicle Electronics & GPS > Car Audio
18805: Vehicle Electronics & GPS > Car Audio > Car Subwoofers
18795: Vehicle Electronics & GPS > Car Audio > Car Amplifiers
39754: Vehicle Electronics & GPS > Car Audio > Car Audio In-Dash Units

Я значительно сократил этот массив до одного примера. Многие категории будут прокачаны до конца, чтобы построить таксономию.

Уровень категории может начинаться с любого числа и заканчиваться с любого числа. В этом примере он начинается с 2, а самый высокий уровень равен 4.

Array
(
    [3270] => Array
        (
            [CategoryID] => 3270
            [CategoryLevel] => 2
            [CategoryName] => Vehicle Electronics & GPS
            [CategoryParentID] => 293
        )

    [175716] => Array
        (
            [CategoryID] => 175716
            [CategoryLevel] => 3
            [CategoryName] => Car Audio
            [CategoryParentID] => 3270
        )


    [79839] => Array
        (
            [CategoryID] => 79839
            [CategoryLevel] => 4
            [CategoryName] => Signal Processors
            [CategoryParentID] => 175716
            [LeafCategory] => true
        )

    [18805] => Array
        (
            [CategoryID] => 18805
            [CategoryLevel] => 4
            [CategoryName] => Car Subwoofers
            [CategoryParentID] => 175716
            [LeafCategory] => true
        )

    [18795] => Array
        (
            [CategoryID] => 18795
            [CategoryLevel] => 4
            [CategoryName] => Car Amplifiers
            [CategoryParentID] => 175716
            [LeafCategory] => true
        )

    [39754] => Array
        (
            [CategoryID] => 39754
            [CategoryLevel] => 4
            [CategoryName] => Car Audio In-Dash Units
            [CategoryParentID] => 175716
            [LeafCategory] => true
        )


)

Заранее благодарю вас за вашу помощь!

Author: Shawn Abramson, 2015-02-23

1 answers

Изменить: Снова исправлена ошибка.

<?php
require_once("samplearray.php");

function makeNestedData($data){
    //create a nested tree using the above structure
    $nested = array();

    //loop over each category
    foreach($data as &$category){
        //is there is no children array, add it
        if(!isset($category['Children'])){
            $category['Children'] = array();
        }
        //check if there is a matching parent
        if(isset($data[$category['CategoryParentID']])){
            //add this under the parent as a child by reference
            if(!isset($data[$category['CategoryParentID']]['Children'])){
                $data[$category['CategoryParentID']]['Children'] = array();
            }
            $data[$category['CategoryParentID']]['Children'][$category['CategoryID']] = &$category;
        //else, no parent found, add at top level
        } else {
            $nested[$category['CategoryID']] = &$category;
        }
    }
    unset($category);
    return $nested;
}

//now flatten out the nested array recursively
function flattenNested($nested, $parent=''){
    $out = array();
    foreach($nested as $category){
        $categoryName = $parent.$category['CategoryName'];
        $out[$category['CategoryID']] = $categoryName;
        //recurse for each child
        $out += flattenNested($category['Children'], $categoryName.' > ');
    }
    return $out;
}

$result = flattenNested(makeNestedData($array));
print_r($result);

Выходные данные:

Array
(
    [3270] => Vehicle Electronics & GPS
    [175716] => Vehicle Electronics & GPS > Car Audio
    [79839] => Vehicle Electronics & GPS > Car Audio > Signal Processors
    [18805] => Vehicle Electronics & GPS > Car Audio > Car Subwoofers
    [18795] => Vehicle Electronics & GPS > Car Audio > Car Amplifiers
    [39754] => Vehicle Electronics & GPS > Car Audio > Car Audio In-Dash Units
)

Вывод представляет собой массив с идентификатором категории справа в качестве ключа, а значение представляет собой строку с текстом категории.

Это может показаться сложным или ненужным способом сделать это, но это действительно один из лучших способов IMO, потому что он будет обрабатывать любой порядок категорий и любое количество вложенных уровней. Единственное ограничение было бы связано с рекурсией и, возможно, памятью, но я пытался использовать ссылки там, где это возможно, чтобы этот объем памяти был как можно меньше.

Пример: http://codepad.viper-7.com/Fke5OA

 3
Author: Jonathan Kuhn, 2015-02-24 00:22:34