我有一个带有stdclasses的一维数组,这些对象有一个名字和一个" abh"属性。 现在我想得到一个像多维数组的树视图。让我们说我的数组看起来像这样:
$ar = array(
(object)array("name" => "Test1","otherstuff"=>array(),"abh"=>""),
(object)array("name" => "Test2","otherstuff"=>array(),"abh"=>"Test1"),
(object)array("name" => "Test3","otherstuff"=>array(),"abh"=>"Test1"),
(object)array("name" => "Test4","otherstuff"=>array(),"abh"=>"Test1"),
(object)array("name" => "Test5","otherstuff"=>array(),"abh"=>"Test1"),
(object)array("name" => "Test6","otherstuff"=>array(),"abh"=>"Test5"),
(object)array("name" => "Test7","otherstuff"=>array(),"abh"=>"Test5"),
(object)array("name" => "Test8","otherstuff"=>array(),"abh"=>array("Test5","Test7")),
(object)array("name" => "Test9","otherstuff"=>array(),"abh"=>"Test8"),
(object)array("name" => "Test10","otherstuff"=>array(),"abh"=>"Test6"),
(object)array("name" => "Test11","otherstuff"=>array(),"abh"=>"Test9"),
);
数据来自之前调用的函数,不是来自数据库。结果是这样的:
Array
(
[0] => stdClass Object
(
[name] => Test1
[otherstuff] => Array
(
)
[abh] =>
)
[1] => stdClass Object
(
[name] => Test2
[otherstuff] => Array
(
)
[abh] => Test1
)
[...]
)
所以现在,我希望这个数组将被" abh"属性。第一个" abh"是空的,它的根,所有其他人将成为它的孩子。所以该功能必须添加一个"孩子"属于主如果它有孩子。但现在这个是特殊类型,因为" abh"可以是一个阵列本身,并重新设置为n父母。在上面的例子中,Test8应该是Test5和Test7(克隆)的孩子。
我尝试使用递归函数处理此问题并在foreach中循环。在那里它检查一个元素的abh而不是父母存在,但不工作。 array_filter()doenst就像我想要的那样。
所以,我想要这个结果:
Array
(
[Test1] => stdClass Object
(
[name] => Test1
[otherstuff] => Array()
[abh] =>
[childs] => Array
(
[Test2] => stdClass Object
[...] and so on
)
)
)
有关于此的任何想法? 我也不知道多少"水平"返回的数组将具有,即多少输入对象和" abh" -assignes存在。秒是" abh"数组最多可以有10个父母"。
感谢您的帮助!
as as requesttet 我的非工作原型" sorter"
function checkABH(&$return,&$ar,$deph) {
// clone all with array-abh
$count = count($ar);
for($x=0;$x<$count;$x++) {#$ar as$key=>$val) {
if(is_array($ar[$x]->abh)) {
$clone = $ar[$x];
foreach($ar[$x]->abh as$abh) {
#echo "<br>$x @@ $abh";
$clone->abh = $abh;
$ar[] = $clone;
#echo '<pre>'.print_r($clone,true).'</pre>';
}
// delete array-abh-element
unset($ar[$x]);
}
}
echo '<pre>'.print_r($ar,true).'</pre>';
echo '</div>';
echo '<div style="float:left;width:auto;margin:0px 10px;"><h3>Result:</h3>';
// pass to sorter
checkABH_a($return,$ar,$deph);
}
function checkABH_a(&$return,&$ar,$deph) {
$test_abhs = array();
foreach($ar as$key=>$val) {
$val->childs = array();
if(isset($return[$deph])&&isset($return[$deph]->name)&&$val->abh==$return[$deph]->name) {
$return[$deph]->childs[] = $val;
unset($ar[$key]);
} elseif($val->abh==$deph) {
$return[$val->abh] = $val;
unset($ar[$key]);
} else {
$test_abhs[] = $val->abh;
}
}
if(count($test_abhs)>0) {
$test_abhs = array_unique($test_abhs);
#echo '<pre>'.print_r($test_abhs,true).'</pre>';
foreach($test_abhs as$abh) {
checkABH_a($return,$ar,$abh);
}
}
}
echo '<div style="float:left;width:260px;border-right:1px solid #cccccc;margin:0px 10px;"><h3>Input</h3>';
echo '<pre>'.print_r($ar,true).'</pre>';
echo '</div>';
echo '<div style="float:left;width:260px;border-right:1px solid #cccccc;margin:0px 10px;"><h3>Cloned:</h3>';
$return = array();
checkABH($return,$ar,"");
echo'<pre>'.print_r($return,true).'</pre>';
echo '</div>';
答案 0 :(得分:1)
这些递归树没有变得容易,添加了“多父”要求是什么; - /无论如何,它看起来仍然很有趣......
我不会在这里记录所有代码,因为我认为我已经对它进行了充分的评论。
注意:
<强> Working version of the code at Viper-7.com using PHP 5.3.18 强>
有关代码的任何查询然后发表评论,我会尝试回答他们。
<?php // https://stackoverflow.com/questions/27360813/php-convert-array-to-multidimensional-array-by-parent-id
$ar = array(
(object) array("name" => "Test1", "otherstuff"=>array('parent is Test1'), "abh"=>""),
(object) array("name" => "Test2", "otherstuff"=>array('parent is Test1'), "abh"=>"Test1"),
(object) array("name" => "Test3", "otherstuff"=>array('parent is Test1'), "abh"=>"Test1"),
(object) array("name" => "Test4", "otherstuff"=>array('parent is Test1'), "abh"=>"Test1"),
(object) array("name" => "Test5", "otherstuff"=>array('parent is Test1'), "abh"=>"Test1"),
(object) array("name" => "Test6", "otherstuff"=>array('parent is Test5'), "abh"=>"Test5"),
(object) array("name" => "Test7", "otherstuff"=>array('parent is Test5'), "abh"=>"Test5"),
(object) array("name" => "Test8", "otherstuff"=>array('parent is Test5 AND Test7'), "abh"=>array("Test5", "Test7")),
(object) array("name" => "Test9", "otherstuff"=>array('parent is Test8'), "abh"=>"Test8"),
(object) array("name" => "Test10", "otherstuff"=>array('parent is Test6'), "abh"=>"Test6"),
(object) array("name" => "Test11", "otherstuff"=>array('parent is Test9'), "abh"=>"Test9"),
);
/*
* The requirement is that for any child then the parent must be in the tree already.
*/
// Convert those parent with 'arrays of parents' into individual entries as it will make the insert
// easier to understand.
// i will also convert all the input into a 'TreeNode' class while i am doing this pass down the input.
// i can add some methods later if i wish.
// i will also get the root of the tree while i am doing this...
$rootNode = new TreeNode(array_shift($ar));
$treeNodeList = array();
foreach($ar as $node) {
if (is_array($node->abh)) { // generate duplicate nodes
foreach($node->abh as $parentName) {
$node->abh = $parentName; // make it an ordinary node
$treeNodeList[] = new TreeNode($node);
}
continue;
}
$treeNodeList[] = new TreeNode($node);
}
// var_dump($ar, $rootNode, $treeNodeList);
// Ok, we now have a node list in the appropriate order - let us build the tree
/**
* This is a 'multiway' tree .i.e. there can be any number of 'child' nodes
* for any parent
* Usual rules:
* o The parent MUST be in the tree already.
* o Children are added, by searching from the root of the tree, in this version
*
*/
// the output will be here
$theTree = array($rootNode->name => $rootNode);
foreach ($treeNodeList as $childNode) { // add it
$inserted = insertNode($rootNode, $childNode);
if (!$inserted) {
var_dump('Unable to insert:', $childNode, ' in tree:', $rootNode);
die('i am here: '. __FILE__.__LINE__);
}
}
// show the tree
echo '<pre>';
print_r($theTree);
echo '</pre>';
exit;
// --------- end of processing -------------
/**
* Insert the node in the tree
*
* @param TreeNode $parent
* @param TreeNode $newChild
*/
function insertNode(TreeNode &$parent, TreeNode $newChild) {
if ($newChild->abh === $parent->name) { // add it to the current parent
$parent->children[$newChild->name] = $newChild; // add child
return true;
}
// check the children
foreach($parent->children as $newParent) {
if (insertNode($newParent, $newChild)) {
return true;
}
}
return false; // unable to insert child in the tree
}
// -----------------------------------------------------------------------
/**
* treeNode: (Data and Relationships)
* nodeId: 'name'
* nodeData: 'otherstuff'
* nodeParentList: 'abh' - may be a list of parents.
* Note: In this version of the code: All the parents
* MUST be in the tree already.
* children: array of treeNode - recursive structure
*/
// i will make the properties all public to make it easier to debug.
class TreeNode {
public $name = '';
public $otherstuff = array();
public $abh = '';
public $children = array(); // list of child nodes
public function __construct(stdClass $node)
{
$this->name = $node->name;
$this->otherstuff = $node->otherstuff;
$this->abh = $node->abh;
}
} // class end --------------------------