想象一下,您有一棵树代表一个您希望保留在表中但保留嵌套级别的家族。我想将下面的帖子数据放入下面的结构中。
我相信 RecursiveIterator 可能是执行此操作的方法,但我不确定我将如何操作。我有适用于大多数情况的代码,但它已经变得丑陋、臃肿。如果你愿意,我可以发布。
stdClass Object
(
[name] => Smith
[type] => Family
[children] => Array(
[1] => stdClass Object
(
[name] => Michael
[type] => Uncle
[children] => Array(
[0] => stdClass Object
(
[name] => Jared
[type] => cousin
)
)
)
[2] => stdClass Object
(
[name] => Jeff
[type] => Dad
[children] => Array(
[0] => stdClass Object
(
[name] => Jonas
[type] => self
)
[1] => stdClass Object
(
[name] => Leah
[type] => sister
[children] => Array(
[0] => stdClass Object
(
[name] => Jacob
[type] => nephew
)
)
)
)
)
)
)
持久化的记录应该是这样的:
Array
(
stdClass Object ( [name] => Smith [type] => Family [subgroup] => 0 [parent_subgroup] => )
stdClass Object ( [name] => Michael [type] => Uncle [subgroup] => 1 [parent_subgroup] => 0 )
stdClass Object ( [name] => Jared [type] => Cousin [subgroup] => 2 [parent_subgroup] => 1 )
stdClass Object ( [name] => Jeff [type] => Dad [subgroup] => 1 [parent_subgroup] => 0 )
stdClass Object ( [name] => Jonas [type] => self [subgroup] => 3 [parent_subgroup] => 1 )
stdClass Object ( [name] => Leah [type] => sister [subgroup] => 3 [parent_subgroup] => 1 )
stdClass Object ( [name] => Jacob [type] => nephew [subgroup] => 4 [parent_subgroup] => 3 )
)
附言不,我和我姐姐没有 child 。那只是我的类比。 ;)
最佳答案
RecursiveIterator
类可能会有点困惑,我喜欢尽量让它们保持简单。您可以使用 RecursiveIteratorIterator
循环遍历迭代器的值,它甚至可以为您提供当前深度(或在您的情况下为 subgroup
)。
这里的挑战是父级不是数组,但我们可以在构造函数中处理它。
<?php
class FamilyIterator implements RecursiveIterator{
private $data, $counter;
public function __construct($familyTree){
$this->data = is_array($familyTree) ? $familyTree : [$familyTree];
}
public function current(){
$row = $this->data[$this->counter];
return (object)[
'name' => $row->name,
'type' => $row->type
];
}
public function key(){
return $this->counter;
}
public function next(){
$this->counter++;
}
public function rewind(){
$this->counter = 0;
}
public function valid(){
return $this->counter < count($this->data);
}
public function hasChildren(){
$row = $this->data[$this->counter];
return isset($row->children);
}
public function getChildren(){
$row = $this->data[$this->counter];
return new self($row->children);
}
}
然后你可以像这样使用这个类:
$loop = new RecursiveIteratorIterator(
new FamilyIterator($dataObj),
RecursiveIteratorIterator::SELF_FIRST
);
当你在 $loop
上 foreach
时,它会在需要时自动调用 getChildren
方法,所以在 foreach
你将拥有每一行。您甚至可以向 RecursiveIteratorIterator
询问深度。
$newData = [];
foreach($loop as $row){
$row->subgroup = $loop->getDepth();
$newData[] = $row;
}
这可能不是正是您想要的,但希望它能为您指明正确的方向。 RecursiveIterator
不需要很复杂。
关于PHP 递归 : Flatten Tree, 保留元数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32912994/