我试图根据字符串的长度创建一个递归数组:字符串长度是节点的级别。这实际上是在Yii框架上构建一个树视图。这是一个例子......
我有一个字符串列表:
Array
(
[0] => A
[1] => C
[2] => CC
[3] => CCC
[4] => P
[5] => PP
[6] => PPP
[7] => PPPE
[8] => PS
[9] => PSA
)
我想对它们进行排序:
Array
(
[0] => Array
(
[text] => A
)
[1] => Array
(
[text] => C
[children] => Array
(
[0] => Array
(
[text] => CC
[children] => Array
(
[0] => Array
(
[text] => CCC
)
)
)
)
)
[2] => Array
(
[text] => P
[children] => Array
(
[0] => Array
(
[text] => PP
[children] => Array
(
[0] => Array
(
[text] => PPP
[children] => Array
(
[0] => Array
(
[text] => PPPE
)
)
)
)
)
[1] => Array
(
[text] => PS
[children] => Array
(
[0] => Array
(
[text] => PSA
)
)
)
)
)
)
我知道我已经找到了具有递归功能的东西,但我不知道该怎么做,尽管事实上我已经尝试了好几天...有人做了类似的事吗那个?非常感谢......
答案 0 :(得分:2)
你的问题是一个奇特的问题,而且我无法帮助我解决这个问题。
我认为您不会发现递归会解决您的问题。原因是为了进行一些递归,你必须自己调用函数。当函数调用自身时,你可能已经对原始数组做了一些工作 - 使(几乎)必须通过引用传递数组的剩余部分。在您的情况下,问题是您希望以递归无法实现的方式重建阵列。 (至少在没有创建令人讨厌的if / else分支来处理你的条件的情况下。)
在你的情况下,我会建议你根据一些条件开展一个可以根据需要进行分类的课程。您的问题需要跟踪一些开销,以便根据需要重建阵列。您需要能够检查(但不限于)以下内容:
text
创建了索引。children
创建了索引。text
或children
。所有这些条件,加上您所需的分类要求,使这项任务最适合一个班级。你的类可以有各种字段来跟踪所有这些条件,并允许你正在使用的任何递归变得更有效。 (好消息是,如果你构建这样一个类并保持类内部的工作,它将很容易移植到其他项目。)
无论如何,这是一个递归函数, 几乎 得到你想要的东西。
<?php
$source = array("A", "C", "CC", "CCC", "P", "PP", "PPP", "PPPE", "PS", "PSA");
$rebuilt = array();
function categorize(&$array)
{
$newArray = array();
if(isset($array[0])) {
$newArray["text"] = $array[0];
array_shift($array);
if(isset($array[0]) && (strlen($newArray["text"]) < strlen($array[0]))) {
if(substr_compare($array[0], $newArray["text"], 0, strlen($newArray["text"])) == 0) {
$newArray["children"] = array(categorize($array));
}
}
}
return $newArray;
}
//Usage:
$sorted = array();
while(count($source) > 0) {
$sorted[] = categorize($source);
}
print_r($sorted);
?>
输出将是:
Array
(
[0] => Array
(
[text] => A
)
[1] => Array
(
[text] => C
[children] => Array
(
[0] => Array
(
[text] => CC
[children] => Array
(
[0] => Array
(
[text] => CCC
)
)
)
)
)
[2] => Array
(
[text] => P
[children] => Array
(
[0] => Array
(
[text] => PP
[children] => Array
(
[0] => Array
(
[text] => PPP
[children] => Array
(
[0] => Array
(
[text] => PPPE
)
)
)
)
)
)
)
[3] => Array
(
[text] => PS
[children] => Array
(
[0] => Array
(
[text] => PSA
)
)
)
)
答案 1 :(得分:2)
这可以给你你想要的东西:
function &createNodeFromText(&$tree, $text)
{
if(strlen($text) > 1) {
//Make sure we have created the parent node(s) we need:
$parent = &createNodeFromText($tree, substr($text, 0, -1));
//Create a new tree level for the current node if needed:
if(!isset($parent["children"])) {
$parent["children"] = array();
}
$currentLevel = &$parent["children"];
}
else {
//New root node:
$currentLevel = &$tree;
}
//Look for the requested node..
$nodeText = $text;
$currentNode = null;
for ($i = 0; $i < count($currentLevel); ++$i) {
$node = &$currentLevel[$i];
if($node["text"] === $nodeText)
{
$currentNode = &$node;
break;
}
}
//..and create a new one only if we have to:
if($currentNode === null) {
$currentNode = array("text" => $nodeText);
$currentLevel[] = &$currentNode;
}
return $currentNode;
}
$source = array("A", "C", "CC", "CCC", "P", "PP", "PPP", "PPPE", "PS", "PSA");
$final = array();
foreach($source as $s) {
createNodeFromText($final, $s);
}
print_r($final);
答案 2 :(得分:1)
<?php
class ArrayRecursiver
{
private $baseArray = array();
private $tmpArray = array();
private function hasParentNode($node)
{
if(strlen($node) > 1)
return true;
else
return false;
}
private function getParentNode($node)
{
return substr($node, 0, -1);
}
private function createNode($node, $existChild = null)
{
$_tmp = array("text" => $node);
if (!empty($existChild))
$_tmp = array("text"=> $node, "children" => $existChild);
if ( $this->hasParentNode($node) )
{
return $this->createNode($this->getParentNode($node), $_tmp);
}
else
{
return $_tmp;
}
}
public function setBase($a)
{
$_tmp = $a;
usort($_tmp, function($a, $b) {
if($a==$b) return 0;
return $a < $b?1:-1;
});
$this->baseArray = $_tmp;
}
public function makeAWish()
{
$prev = null;
foreach ($this->baseArray as $key => $node)
{
$_tmp = $this->createNode($node);
$this->tmpArray[]= $_tmp;
}
return $this->tmpArray;
}
}// end class ArrayRecursiver
$badArray = array(
"A","C","CC","CCA","P","PP","PPP","PPPE","PS","PSA"
);
echo "<pre>";
$worker = new ArrayRecursiver();
$worker->setBase($badArray);
print_r($worker->makeAWish());
echo "</pre>";
它几乎可以满足你的需要;) 我说几乎;)你现在需要重建返回的数组,我希望这有帮助你