我有一个数组,我知道所需的输出,但我无法理解如何实现它
初始索引是"父母" id' s,其中包含的数组是孩子,但有些孩子也是父母
我的阵列: ```
array:10 [▼
0 => array:2 [▼
0 => 1
1 => 5
]
1 => array:1 [▼
0 => 2
]
2 => array:2 [▼
0 => 3
1 => 4
]
5 => array:1 [▼
0 => 6
]
6 => array:2 [▼
0 => 7
1 => 8
]
9 => array:2 [▼
0 => 10
1 => 22
]
10 => array:1 [▼
0 => 11
]
11 => array:10 [▼
0 => 12
1 => 13
2 => 14
3 => 15
4 => 16
5 => 17
6 => 18
7 => 19
8 => 20
9 => 21
]
22 => array:1 [▼
0 => 23
]
23 => array:2 [▼
0 => 24
1 => 25
]
]
```
结果数组: ```
0
9
0,1
0,5
0,1,2
0,1,2,3
0,1,2,4
0,5,6
0,5,6,7
0,5,6,8
9,10
9,22
9,10,11
9,10,11,12
9,10,11,13
9,10,11,14
9,10,11,15
9,10,11,16
9,10,11,17
9,10,11,18
9,10,11,19
9,10,11,20
9,10,11,21
9,22,23
9,22,23,24
9,22,23,25
```
我正在考虑使用递归,但我不能为我的生活找出如何获得结果
编辑:更多信息:
如果我采取:
22 => array:1 [▼
0 => 23
]
23 => array:2 [▼
0 => 24
1 => 25
]
23是24和25的父母,22是23的父母,因此22是24和25的祖父母:
9,22,23,24
9,22,23,25
你是如何得到这个清单的(9显然是22的父母,因此是23岁的祖父母和24岁和25岁的祖父母)
答案 0 :(得分:1)
这有点高级,但您可以使用Iterators
来实现这一目标。
首先,我们必须延长RecursiveIteratorIterator
以满足我们的需求:
class FlatRecursiveIteratorIterator extends RecursiveIteratorIterator
{
private $directory;
public function __construct(
Traversable $iterator,
$mode = RecursiveIteratorIterator::LEAVES_ONLY,
$flags = 0,
array $directory
) {
// Set array for children lookup.
$this->directory = $directory;
parent::__construct($iterator, $mode, $flags);
}
public function callHasChildren()
{
if ($this->getDepth() === 0 && is_array($this->current())) {
return true;
}
// See if children array availale in the top most array
// (lookup by id).
return !empty($this->directory[$this->current()]) &&
is_array($this->directory[$this->current()]);
}
public function callGetChildren()
{
return new RecursiveArrayIterator(
$this->getDepth() === 0
? $this->current()
: $this->directory[$this->current()]
);
}
}
有了这个课程,我们会将其与RecursiveArrayIterator
和RecursiveCallbackFilterIterator
结合使用,以创建所需的$iterator
:
$skip = [];
$iterator = new FlatRecursiveIteratorIterator(
// This filter helps up skip top level array elements
// if they have ancestors. Pay attencion that $skip passed by reference.
new RecursiveCallbackFilterIterator(
new RecursiveArrayIterator($array),
function ($current, $key, $_) use (&$skip) {
return !(is_array($current) && isset($skip[$key]));
}
),
RecursiveIteratorIterator::SELF_FIRST,
0,
$array
);
然后我们可以使用一个非常简单的非嵌套循环来遍历这个$iterator
:
$stack = [];
foreach ($iterator as $node) {
$depth = $iterator->getDepth();
if ($depth > 0) {
$skip[$node] = true;
}
// Use ternary operator as top most array has ids as keys,
// but inner arrays have ids as values.
$stack[$depth] = $depth === 0
? $iterator->key()
: $node;
// We have to slice out stack, as it may contain elements
// from previous iterations.
echo implode(',', array_slice($stack, 0, $depth + 1)), PHP_EOL;
}
这是working demo。
这可能看起来像很多代码,但实际上并非如此。我们需要考虑到大部分工作都是由Standard PHP Library完成的。我们只编写了大多数案例特定的代码。