查找数组中的所有后代
Find all descendants in array
乍一看很简单,但当我尝试解决它时,我感到很困惑。
我有 PHP 数组,其中键是前 parent 个 ID,值是 child 个 ID。一些 child ID 有自己的 children。那children可能有自己的children等等。
我的目标是获得一个新数组,其中所有排名靠前的 parent ID 都有其所有级别的所有后代(children、grandchildren、曾祖父children 和依此类推)。
<?php
// Source array
$source = array(
'24' => array(
'23',
'22'
),
'25' => false,
'22' => array(
'21'
),
'21' => array(
'20'
),
'20' => array(
'19'
),
'19' => array(
'18'
),
'18' => array(
'17'
)
);
// Result array I need to achieve
$result = array(
'24' => array(
'23',
'22',
'21',
'20',
'19',
'18',
'17'
),
'22' => array(
'21',
'20',
'19',
'18',
'17'
),
'21' => array(
'20',
'19',
'18',
'17'
),
'20' => array(
'19',
'18',
'17'
),
'19' => array(
'18',
'17'
),
'18' => array(
'17'
)
);
?>
接下来是我的尝试:
<?php
function get_all_descendants($source)
{
$result = $source;
foreach ($source as $parent_id => $children) {
foreach ($children as $op) {
if (isset($source[$op])) {
foreach ($source[$op] as $bottom_level_id) {
$result[$parent_id][] = $bottom_level_id;
}
}
}
}
return $result;
}
var_dump( get_all_descendants( $source ) );
array(7) {
[24]=>
array(3) {
[0]=>
string(2) "23"
[1]=>
string(2) "22"
[2]=>
string(2) "21"
}
[25]=>
bool(false)
[22]=>
array(2) {
[0]=>
string(2) "21"
[1]=>
string(2) "20"
}
[21]=>
array(2) {
[0]=>
string(2) "20"
[1]=>
string(2) "19"
}
[20]=>
array(2) {
[0]=>
string(2) "19"
[1]=>
string(2) "18"
}
[19]=>
array(2) {
[0]=>
string(2) "18"
[1]=>
string(2) "17"
}
[18]=>
array(1) {
[0]=>
string(2) "17"
}
}
?>
但是这个函数并没有找到所有的后代,看起来应该是递归的,但是我想不出怎么写。一般来说,我过去用递归写过不同的函数,但在这种情况下我打破了我的想法)
您可以使用堆栈或递归,然后深度优先探索结构:
<?php
function find_all_descendents($arr) {
$all_results = [];
foreach ($arr as $k => $v) {
$curr_result = [];
for ($stack = [$k]; count($stack);) {
$el = array_pop($stack);
if (array_key_exists($el, $arr) && is_array($arr[$el])) {
foreach ($arr[$el] as $child) {
$curr_result []= $child;
$stack []= $child;
}
}
}
if (count($curr_result)) {
$all_results[$k] = $curr_result;
}
}
return $all_results;
}
$source = [
'24' => ['23', '22'],
'25' => false,
'22' => ['21'],
'21' => ['20'],
'20' => ['19'],
'19' => ['18'],
'18' => ['17']
];
var_dump(find_all_descendents($source));
乍一看很简单,但当我尝试解决它时,我感到很困惑。
我有 PHP 数组,其中键是前 parent 个 ID,值是 child 个 ID。一些 child ID 有自己的 children。那children可能有自己的children等等。 我的目标是获得一个新数组,其中所有排名靠前的 parent ID 都有其所有级别的所有后代(children、grandchildren、曾祖父children 和依此类推)。
<?php
// Source array
$source = array(
'24' => array(
'23',
'22'
),
'25' => false,
'22' => array(
'21'
),
'21' => array(
'20'
),
'20' => array(
'19'
),
'19' => array(
'18'
),
'18' => array(
'17'
)
);
// Result array I need to achieve
$result = array(
'24' => array(
'23',
'22',
'21',
'20',
'19',
'18',
'17'
),
'22' => array(
'21',
'20',
'19',
'18',
'17'
),
'21' => array(
'20',
'19',
'18',
'17'
),
'20' => array(
'19',
'18',
'17'
),
'19' => array(
'18',
'17'
),
'18' => array(
'17'
)
);
?>
接下来是我的尝试:
<?php
function get_all_descendants($source)
{
$result = $source;
foreach ($source as $parent_id => $children) {
foreach ($children as $op) {
if (isset($source[$op])) {
foreach ($source[$op] as $bottom_level_id) {
$result[$parent_id][] = $bottom_level_id;
}
}
}
}
return $result;
}
var_dump( get_all_descendants( $source ) );
array(7) {
[24]=>
array(3) {
[0]=>
string(2) "23"
[1]=>
string(2) "22"
[2]=>
string(2) "21"
}
[25]=>
bool(false)
[22]=>
array(2) {
[0]=>
string(2) "21"
[1]=>
string(2) "20"
}
[21]=>
array(2) {
[0]=>
string(2) "20"
[1]=>
string(2) "19"
}
[20]=>
array(2) {
[0]=>
string(2) "19"
[1]=>
string(2) "18"
}
[19]=>
array(2) {
[0]=>
string(2) "18"
[1]=>
string(2) "17"
}
[18]=>
array(1) {
[0]=>
string(2) "17"
}
}
?>
但是这个函数并没有找到所有的后代,看起来应该是递归的,但是我想不出怎么写。一般来说,我过去用递归写过不同的函数,但在这种情况下我打破了我的想法)
您可以使用堆栈或递归,然后深度优先探索结构:
<?php
function find_all_descendents($arr) {
$all_results = [];
foreach ($arr as $k => $v) {
$curr_result = [];
for ($stack = [$k]; count($stack);) {
$el = array_pop($stack);
if (array_key_exists($el, $arr) && is_array($arr[$el])) {
foreach ($arr[$el] as $child) {
$curr_result []= $child;
$stack []= $child;
}
}
}
if (count($curr_result)) {
$all_results[$k] = $curr_result;
}
}
return $all_results;
}
$source = [
'24' => ['23', '22'],
'25' => false,
'22' => ['21'],
'21' => ['20'],
'20' => ['19'],
'19' => ['18'],
'18' => ['17']
];
var_dump(find_all_descendents($source));