【问题标题】:How to follow parent-child relationships in a multi-dimensional array?如何在多维数组中遵循父子关系?
【发布时间】:2018-09-21 18:07:07
【问题描述】:

我有一个像这样的多级类别的经典数据库表(0 表示根):

ID - Name - Father
1    News      0
2    Articles  0
3    Politics  1
4    Politics  2
5    World     3
6    World     4

我有一个这样的路径:/News/Articles/Politics,并且我有一个数组中的上述表格数据。

我从路径上的/ 调用explode() 开始,我尝试了一些方法,但在所有情况下都不好。

这是我尝试过的:

$cat_path_ary = explode($cfg['categories_separator'], $cat_path);
if (count($cat_path_ary) > 1) {
    $catname = array_pop($cat_path_ary);
    $catparent = array_pop($cat_path_ary);
    $cat_id = $this->getCatIDbyName($plugin, $catname, $catparent);
} else {
   $catname = $cat_path_ary[0];
   foreach($this->root_cats($plugin) as $categories) {
      if($categories['name'] == $catname ) {
       return $categories['cid'];
      }
   }
}

遍历路径值并确定最终值的ID 的最佳方法是什么?

来自/News/Articles/Politics 我希望返回5

【问题讨论】:

  • 所以基本上你想遍历树?
  • 基本上如果我有 /News/Politics/World 我想要一个返回 id '5' 的函数
  • 这个问题够清楚,也不算太宽泛。 OP 提供了一个编码尝试,它比该站点上的许多“给我代码”问题要好。我已投票决定保持开放并投了赞成票。这是一个受欢迎的问题,我们不要抑制发布这种质量的问题。
  • 不幸的是,这里有更多的人对标记为重复和否定感兴趣而不是帮助,感谢您编辑我糟糕的英语。

标签: php loops search tree categories


【解决方案1】:

我很少推荐对数据库进行迭代调用,这种情况也不例外。 由于您的结果集应该相对较小,因此您可以执行全表查询并处理多维数组以获得所需的输出。

迭代路径中的条目并对符合条件的行执行迭代检查(匹配 Name 和匹配 Father)。

由于每个内部循环只能有一个合格的行,所以break 一旦找到它就可以达到最佳效率。 ...请务必在更新之前更新 $id$parent 变量。

已实施“无符合条件的行”检查,但它可能与您的项目相关,也可能不相关。您可以决定是否需要这个安全网。

代码:(Demo)

$resultset = [                                                     // query just once, collect the full tree
    ["ID" => 1, "Name" => "News", "Father" => 0],
    ["ID" => 2, "Name" => "Articles", "Father" => 0],
    ["ID" => 3, "Name" => "Politics", "Father" => 1],
    ["ID" => 4, "Name" => "Politics", "Father" => 2],
    ["ID" => 5, "Name" => "World", "Father" => 3],
    ["ID" => 6, "Name" => "World", "Father" => 4]
];

$path = "/News/Politics/World";
// $path = "/Articles/The Funnies/Garfield";                        // a test case that fails
// News: parent = 0, id = 1                                         // \
// Politics: parent = 1, id = 3                                     //  > the intended logic
// World: parent = 3, id = 5                                        // /

$cfg['categories_separator'] = "/";
$breadcrumbs = explode($cfg['categories_separator'], trim($path, "/"));
// var_export($breadcrumbs);                                        // see what is generated

$parent = 0;                                                        // default value
foreach ($breadcrumbs as $crumb) {
    $id = false;                                                    // set invalid value for success check
    foreach ($resultset as $row) {
        if ($row["Name"] == $crumb && $parent == $row["Father"]) {  // qualifying match
            $id = $parent = $row["ID"];                             // dual declaration
            break;                                                  // break inner loop, progress to next $crumb        
        }
    }
    if (!$id) {                                                     // inner loop failed to find qualifying match
        echo "Uh-oh, Broken Breadcrumb Path -- $crumb not found in $path\n";
        break;                                                      // break outer loop, path is invalid
    }
    // echo "ID = $id for $crumb\n";                                // uncomment to see progress
}
echo "ID = $id for $crumb\n";                                       // echo the result

输出:

ID = 5 for World

【讨论】:

  • 我在睡前自己做,用双行代码、额外的函数调用和三个循环。这段代码无限好,更优雅,而且运行良好,谢谢。解决了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-11
  • 2013-11-03
  • 2017-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多