我有這樣一個樹:走樹木PHP
$tree = array("A", array(
array("B", 1),
array("C", 2),
array("D",
array("E",
array("F")),
array("G")),
array("H", 3)));
每個節點是一個數組,節點的類型是它的第一個元素和其他元素節點的參數(也可以是列表其他節點,單個節點,一些值等;節點可以沒有參數,一個參數或多個參數)。
您認爲最優雅的方式來走這些類型的樹木?
我想出了兩種可能性:
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)每個節點類型的方法對象
/*
* + 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) { /*...*/ }
}
還是你建議更優雅行走樹的方式?
我也認爲節點是對象,而不是獨立的樹步行者,每個節點都有內部散步的方法。不過,我認爲這會讓代碼難以維護,因爲步行者代碼的一部分將被放置在不同的位置,並且使用相同的代碼更難以用於更多的節點。
的問題是所有節點都不會被處理一樣。仍然需要開關或其他東西。或者我錯過了什麼? – 2010-06-22 20:56:37
@Jak遍歷本身獨立於數據結構,只要它們是可迭代的。如果你想對待不同的元素,是的,你仍然需要一個switch語句,或者你可以使用對象而不是數組,並利用動態分派。 – Artefacto 2010-06-22 22:16:54
正如我在我的問題中寫的那樣,我考慮過對象,我認爲它們會比弊端更壞。 – 2010-06-23 13:48:19