[英]The most elegant way to walk trees in PHP
I have trees like this one: 我有这样的树:
$tree = array("A", array(
array("B", 1),
array("C", 2),
array("D",
array("E",
array("F")),
array("G")),
array("H", 3)));
Each node is an array, type of node is its first element and other elements are node's arguments (they can be list of other nodes, single node, some value etc.; node can have no argument, one argument or more arguments). 每个节点都是一个数组,节点的类型是其第一个元素,其他元素是节点的参数(它们可以是其他节点的列表,单个节点,某些值等;节点可以没有参数,一个参数或多个参数)。
What do you think is the most elegant way to walk these type of trees? 您认为走这类树的最优雅方式是什么?
I came up with two possibilities: 我想出了两种可能性:
1) using switch
statement 1)使用switch
语句
/*
* + shorter
* + fall-througs (easy way to handle more nodes with same code)
*
* - worse readability
*/
function my_tree_walker($tree)
{
switch ($tree[0]) {
case 'A':
list($_, $subnodes) = $tree;
$ret = '';
foreach ($subnodes as $subnode) {
$ret .= my_tree_walker($subnode);
}
return $ret;
break;
case 'B': /*...*/ break;
case 'C': /*...*/ break;
case 'D': /*...*/ break;
case 'E': /*...*/ break;
case 'F': /*...*/ break;
case 'G': /*...*/ break;
case 'H': /*...*/ break;
}
}
2) object with method for each node type 2)每种节点类型的方法对象
/*
* + better readability
* + more declarative
*
* - longer
* - `new static` is PHP >=5.3 only
*/
abstract class TreeWalker
{
protected function __construct(){}
final protected function walk($node)
{
$nodetype = array_shift($node);
return call_user_func_array(array($this, 'walk' . $nodetype), $node);
}
public static function w($tree)
{
$instance = new static;
return $instance->walk($tree);
}
}
final class MyTreeWalker extends TreeWalker
{
protected function __construct()
{
// initialize
}
private function walkA($subnodes)
{
$ret = '';
foreach ($subnodes as $subnode) {
$ret .= $this->walk($subnode);
}
return $ret;
}
private function walkB($n) { /*...*/ }
private function walkC($n) { /*...*/ }
private function walkD($subnode) { /*...*/ }
private function walkE() { /*...*/ }
private function walkF() { /*...*/ }
private function walkG() { /*...*/ }
private function walkH($n) { /*...*/ }
}
Or do you suggest even more elegant way of walking trees? 还是您建议使用更优雅的步行树方式?
I also considered nodes being objects and instead of separate tree walkers each node would have methods for walks inside. 我还认为节点是对象,并且每个节点将具有在内部进行遍历的方法,而不是单独的树遍历。 However I think it will make code harder to maintain, because parts of walkers' code will be placed in different locations and it will be harder to use same code for more nodes. 但是我认为这将使代码难以维护,因为步行者的部分代码将放置在不同的位置,并且将相同的代码用于更多的节点将变得更加困难。
Take a look at: 看一眼:
I think simplicity is elegant. 我认为简单是优雅的。
No need to reinvent the wheel! 无需重新发明轮子! PHP comes equipped with SPL (Standard PHP Library) which offers several Iterators that can do all the work for you. PHP配备了SPL(标准PHP库) ,它提供了多个迭代器 ,可以为您完成所有工作。
A few to check out would be RecursiveIteratorIterator
and RecursiveArrayIterator
要检查的几个是RecursiveIteratorIterator
和RecursiveArrayIterator
I combined both ways and created DSL: 我结合了两种方式并创建了DSL:
A ($subnodes) {
$ret = '';
foreach ($subnodes as $subnode) {
$ret .= WALK($subnode);
}
return $ret;
}
B ($n) { /*...*/ }
C ($n) { /*...*/ }
D ($subnode) { /*...*/ }
E () { /*...*/ }
F () { /*...*/ }
G () { /*...*/ }
H ($n) { /*...*/ }
that is translated to PHP. 即翻译为PHP。
I recommend this library: https://packagist.org/packages/lukascivil/treewalker 我推荐这个图书馆: https : //packagist.org/packages/lukascivil/treewalker
TreeWalker is a simple and small Library that will help you to work faster with manipulation of structures in PHP TreeWalker是一个简单的小型库,它将帮助您更快地处理PHP中的结构
I made a simple recursive function that effectively walks a tree. 我做了一个简单的递归函数,可以有效地走树。 Here it is 这里是
function deep_cetegories($categories){
foreach($categories as $category)
{
print_r((json_encode($category['category_name'])));
if(isset($category['children']))
{
deep_cetegories($category['children']);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.