给出以下多维数组:
$family = array(
"grandfather",
"grandmother",
"father" => array(
"parents" => array(
"grandfather",
"grandmother"
)
),
"mother" => array(
"parents" => array(
"grandfather",
"grandmother"
)
),
"son" => array(
"parents" => array(
"father",
"mother"
)
),
"daughter" => array(
"parents" => array(
"father",
"mother"
)
),
);
你可以想象将这个阵列扩展到包括曾祖父母,曾孙子等等。
我确信这是一个常见且记录良好的数据结构,但我不是计算机科学专业,我不知道如何描述或命名这种特殊类型的字典。
是否有一个内置于PHP的函数可以可靠地导航这个树,给定一个“子”节点的名称和我们正在寻找的“祖先”节点?
例如:
getAncestor($array, $child, $ancestor);
我试过这个,它通常涉及嵌套在其内部的getAncestor()函数的递归,但有时会遇到“死胡同”,它会一直导航到一个分支的末尾。< / p>
答案 0 :(得分:0)
你可以尝试更线性的方法,而不是将所有内容嵌套在一起,你只需要一堆指向每个对象中所有祖先的指针。否则这听起来像是一个递归问题。
指针方法:
<?php
$person1 = new PersonObject( 'details' );
$person2 = new PersonObject( 'details' );
$person1->father =& $person2;
?>
如果您的数据集与您的示例一样,您可能会或可能不会从转换到此类系统中受益,具体取决于您需要查找的祖先数量。此外,在我看来,这种结构更清洁=)。
答案 1 :(得分:0)
抱歉,但我无法想象如何在没有看到的情况下添加曾祖父母。你说要求递归,但$family
有3代成员,只有2级嵌套。如果您要像这样添加曾祖父母(根据您的样本$family
数组我的最佳猜测),仍然只有2级嵌套。
$family = array(
"great-grandfather",
"great-grandmother",
"grandmother" => array(
"parents" => array(
"great-grandmother",
"great-grandfather"
)
),
// ...
);
然后甚至不需要递归。
虽然根据你的描述不清楚它应该做什么完全。当找到匹配项时,它会回显子项和祖先,并返回布尔结果。
function getAncestor($array, $child, $ancestor)
{
foreach($array as $_child => $_ancestor) {
// Bail if child is not a match or ancestor is not array
if($child != $_child ||
!is_array($_ancestor) || !count($_ancestor))
continue;
// see if cur ancestor is a match for searched ancestor
if(in_array($ancestor, $_ancestor['parents'])) {
echo 'Child: ' . $child . PHP_EOL;
echo 'Ancestors: ' . implode(', ', $_ancestor['parents']) . PHP_EOL;
return true;
}
}
return false;
}
getAncestor($family, 'son', 'father');
getAncestor($family, 'father', 'grandmother');
getAncestor($family, 'father', 'mother');
输出
孩子:儿子
祖先:父亲,母亲
孩子:父亲
祖先:祖父,祖母
关于示例$family
的另一个旁注,看起来像父亲和母亲拥有相同的父母!