按类别划分的树图

时间:2016-12-02 23:52:58

标签: php

我正在尝试从类别构建树形图。

我有类别(我有很多类别,我想删除重复项并在树形图视图中显示它们)

$cat = array(
    "Sneakers/Men",
    "Sneakers/Women",
    "Accessories/Jewellery/Men",
    "Accessories/Jewellery/Women",
    "Accessories/Jewellery/Men
");

......我希望他们像这样

$categories = array(
    "Sneakers" => array(
        "Men" => array(),
        "Women" => array()
    ),
    "Accessories" => array(
        "Jewellery" => array(
            "Men" => array(),
            "Women" => array()
        )
    )
);

像这样打印它们

- Sneakers
-- Men
-- Women

- Accessories
-- Jewellery
--- Men
--- Women

1 个答案:

答案 0 :(得分:2)

最简单的方法是使用引用,如下所示:

$out = [];
foreach ($cat as $str) {
    $lookup =& $out;
    foreach (explode("/", $str) as $part) {
        $lookup =& $lookup[$part];
        if (!isset($lookup)) {
            $lookup = [];
        }
    }
}

$lookup最初引用整个预期结果,然后在每一步扩展引用以遵循嵌套成员的路径。

请注意,添加的每个新成员看起来都像member-name => [],所以实际上甚至最终的叶子都是数组:它可能看起来有点奇怪,但这是一种减少代码的一种很好的方式(每个成员总是准备好接待孩子们。)

然而,使用生成的数组然后像OP一样打印它并不困难:

function nest_print($src, $level = 0) {
    $prefix = '<br />' . str_repeat('- ', ++$level);
    foreach ($src as $key => $val) {
      echo $prefix . $key;
      if ($val) {
          nest_print($val, $level);
      }
    }
}

nest_print($out);

修改

这是一个替代解决方案,包括OP在他的评论中提出的最终假期数:

$out = [];
foreach ($cat as $str) {
    $lookup =& $out;
    $parts = explode("/", $str);
    foreach ($parts as $part) {
        $lookup =& $lookup[$part];
        if (!isset($lookup)) {
            $lookup = [];
        }
        // when $part is a final leaf, count its occurrences
        if ($part == end($parts)) {
            $lookup = is_array($lookup) ? 1 : ++$lookup;
        }
    }
}

(可能会以更优雅的方式改进)

以下是如何相应地修改打印结果片段:

function nest_print($src, $level = 0) {
    $prefix = '<br />' . str_repeat('- ', ++$level);
    foreach ($src as $key => $val) {
      echo $prefix . $key;
      if (is_array($val)) {
          nest_print($val, $level);
      } else {
          echo ': ' . $val;
      }
    }
}

nest_print($out);