数组中的类别层次结构(cat id => parent id)

时间:2014-11-27 04:03:39

标签: php arrays multidimensional-array hierarchy

我正在尝试从包含类别ID和父ID的简单数组创建多维数组层次结构。类别可以同时是父类和子类。基类别的父级为0(=无父级)。例如:

# cat_id => parent_id
$initialArray = array(
  1 => 0,
  2 => 1,
  3 => 2,

  4 => 0,
  5 => 4,

  6 => 0
);

由此,我想得到一个代表这样结构的数组:

  • 1
    • 2
      • 3
  • 4
    • 5
  • 6

我事先不会知道$initialArray的内容。

我试着看其他类似的问题,但我找不到答案。请帮忙!

6 个答案:

答案 0 :(得分:2)

我知道,迟到了派对,但看起来很有意思......

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

它将从根节点开始一次插入一个节点。对于大树来说它会变得非常昂贵。

工作示例:Viper-7.com

完成工作的例程:

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

注意:

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

给定的输入节点列表是'child'=> '父母'命令是不寻常的,没关系,只记得在处理中......

处理输入数据:

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

输入列表需要被激活,以便加载“树”,使得要添加的子项的父项必须已经在树中。 我假设输入列表已按要求的顺序

测试数据,排序和显示:

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

输出,我在原始输入中添加了一个子树...

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
                (
                )
        )
  )

答案 1 :(得分:1)

有什么办法可以改变数组的生成方式吗?正如你现在所拥有的那样,尝试生成你想要的东西会更麻烦。

或者,你可以尝试生成这样的东西:

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

允许这样的简单循环:

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

以上是模板语法,我确定我们都知道这是什么,所以我现在要解释它。

或简单的循环看起来像这样:

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

答案 2 :(得分:1)

获取清单:

<?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

答案 3 :(得分:1)

在我看来你需要一个递归函数。假设一切都有一个父级或值从0开始的基础级别,我重新定义了数组,让所有的父ID列出他们的孩子而不是上面的其他方式。之后,我创建了一个递归函数。

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

输出:

// 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
        )

)

答案 4 :(得分:0)

你可以制作这样的数组

$initialArray = array();
$initialArray[parent_id][cat_id]='your_value';   //$initialArray[0][0] ... and then increasing

答案 5 :(得分:0)

如果你想形成一个递归数组,你可以参考这个页面

Recursive function to generate multidimensional array from database result

这可能对你有很大的帮助。感谢。