我不知道。我在谷歌上搜索,在这里搜索,阅读php手册几个小时,但我不能想出一个解决方案。
我得到了以下数组结构:
[x] => Array
(
...
[object_name_1] => Array
(
[db] => x
[form] => y
[value] => z
)
...
[object_name_4] => Array
(
[db] => x
[form] => y
[value] => z
)
...
[object_name_n] => Array
(
[db] => x
[form] => y
[value] => z
)
...
[y] => Array
(
...
[object_group_xyz] => Array
(
[object_name_a] => Array
(
[db] => x
[form] => y
[value] => z
)
...
)
...
[object_name_e] => Array
(
[db] => x
[form] => y
[value] => z
)
...
[object_name_z] => Array
(
[db] => x
[form] => y
[value] => z
)
现在我的问题是:我想保存所有object_name_x数组。数组的深度是未知的,事实上,不同的object_name_n对象的深度可以依赖于同一个数组。但他们永远是最后一片叶子。
我怎样才能解决这个问题?据我所知,RecursiveIteratorIterator不可能只考虑倒数第二个对象。
我的输出应该是这样的:
Array
(
[object_name_1] => Array
(
[db] => x
[form] => y
[value] => z
)
...
[object_name_4] => Array
(
[db] => x
[form] => y
[value] => z
)
...
[object_name_n] => Array
(
[db] => x
[form] => y
[value] => z
)
...
[object_name_a] => Array
(
[db] => x
[form] => y
[value] => z
)
...
[object_name_e] => Array
(
[db] => x
[form] => y
[value] => z
)
...
[object_name_z] => Array
(
[db] => x
[form] => y
[value] => z
)
...
)
感谢您的时间和帮助!
这不是迭代器类的内置功能,但您仍然可以使用RecursiveIteratorIterator
并构建堆栈,以便在到达叶节点时可以后退一步。
下面是一个PoC,它不是一个超级干净的解决方案,但它是有效的,应该展示原则:
class MyIterator extends RecursiveIteratorIterator {
protected $stack = array();
protected $result = array();
public function __construct($data)
{
parent::__construct(new RecursiveArrayIterator($data), RecursiveIteratorIterator::SELF_FIRST);
}
public function getObjects()
{
foreach($this as $dummy);
return $this->result;
}
public function rewind()
{
parent::rewind();
$this->stack = array();
$this->result = array();
$this->pushIfNoLeaf();
}
public function next()
{
parent::next();
$this->pushIfNoLeaf();
}
public function beginIteration()
{
parent::beginIteration();
$this->popIfLeaf();
}
public function beginChildren()
{
parent::beginChildren();
$this->popIfLeaf();
}
protected function pushIfNoLeaf()
{
if ($this->getSubIterator()->hasChildren()) {
$this->stack[] = array('key' => $this->key(), 'value' => $this->current());
}
}
protected function popIfLeaf()
{
if (!$this->getSubIterator()->hasChildren()) {
$item = array_pop($this->stack);
$this->result[$item['key']] = $item['value'];
}
}
}
$data = array(
'obj1' => array(1,2,3),
'arr1' => array(
'obj2' => array(4,5,6),
'obj3' => array(7,8,9)
)
);
$iterator = new MyIterator($data);
var_dump($iterator->getObjects());
示例输出
array(3) {
["obj1"]=>
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
["obj2"]=>
array(3) {
[0]=>
int(4)
[1]=>
int(5)
[2]=>
int(6)
}
["obj3"]=>
array(3) {
[0]=>
int(7)
[1]=>
int(8)
[2]=>
int(9)
}
}
class MyIterator extends RecursiveIteratorIterator {
protected $stack = array();
protected $result = array();
public function __construct($data)
{
parent::__construct(new RecursiveArrayIterator($data), RecursiveIteratorIterator::SELF_FIRST);
}
public function getObjects()
{
foreach($this as $dummy);
return $this->result;
}
public function rewind()
{
parent::rewind();
$this->stack = array();
$this->result = array();
$this->pushIfNoLeaf();
}
public function next()
{
parent::next();
$this->pushIfNoLeaf();
}
public function beginIteration()
{
parent::beginIteration();
$this->popIfLeaf();
}
public function beginChildren()
{
parent::beginChildren();
$this->popIfLeaf();
}
protected function pushIfNoLeaf()
{
if ($this->getSubIterator()->hasChildren()) {
$this->stack[] = array('key' => $this->key(), 'value' => $this->current());
}
}
protected function popIfLeaf()
{
if (!$this->getSubIterator()->hasChildren()) {
$item = array_pop($this->stack);
$this->result[$item['key']] = $item['value'];
}
}
}
$data = array(
'obj1' => array(1,2,3),
'arr1' => array(
'obj2' => array(4,5,6),
'obj3' => array(7,8,9)
)
);
$iterator = new MyIterator($data);
var_dump($iterator->getObjects());
array(3) {
["obj1"]=>
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
["obj2"]=>
array(3) {
[0]=>
int(4)
[1]=>
int(5)
[2]=>
int(6)
}
["obj3"]=>
array(3) {
[0]=>
int(7)
[1]=>
int(8)
[2]=>
int(9)
}
}
像这样使用end
和prev
:
$array = array('one' => 1, 'two' => 2, 'three' => 3);
end($array);
echo prev($array); // Ouputs 2
echo key($array); // Ouputs 'two'
在你的例子中,你应该有:
$array = array(
0 => array(
0 => (object) array('name' => 'a'),
1 => (object) array('name' => 'b'),
2 => (object) array('name' => 'c'),
),
1 => array(
3 => (object) array('name' => 'd'),
4 => (object) array('name' => 'e'),
5 => (object) array('name' => 'f'),
),
);
$objects = array();
foreach ($array as $a)
{
end($a);
$prev = prev($a);
$objects[key($a)] = $prev;
}
echo '<pre>' . print_r($objects, TRUE) . '</pre>';
输出:
Array
(
[1] => stdClass Object
(
[name] => b
)
[4] => stdClass Object
(
[name] => e
)
)