【发布时间】:2015-02-28 01:03:41
【问题描述】:
我需要从一个人(作为 $id 参数传递)开始返回“x”代(作为 $generations 参数传递)的家庭数据(父母、兄弟姐妹和伴侣)。我不能假设有两个父母,这个特定的家谱模型必须允许动态数量的父母(允许生物和收养关系)。我认为我的递归是向后的,但我不知道如何。
下面的代码触发了我的基本子句 5 次,每一代一次,因为 $generation 不是针对每个 SET 父母而是针对每个父母减少 1。我想要的是只触发一次基本子句($generations == 0),当获取初始人的所有父母的“x”代时。
public function fetchRelationships($id = 1, $generations = 5, $relationships = array())
{
$perId = $id;
if ($generations == 0) {
return $relationships;
} else {
$parents = $this->fetchParents($perId);
$relationships[$perId]['parents'] = $parents;
$relationships[$perId]['partners'] = $this->fetchPartners($perId);
if (!empty($parents)) {
--$generations;
foreach ($parents as $parentRel) {
$parent = $parentRel->getPer2();
$pid = $parent->getId();
$relationships[$perId]['siblings'][$pid] = $this->fetchSiblings($perId, $pid);
$perId = $pid;
$relationships[$perId] = $this->fetchRelationships($perId, $generations, $relationships);
}
}
return $relationships;
}
}
fetchPartners、fetchParents 和 fetchSiblings 方法只是获取匹配的实体。所以我不会在这里粘贴它们。假设有 2 个父代,5 代并且每一代有 2 个父代,那么返回数组应该包含 62 个元素,并且只有在这 62 个元素被填充后才应该触发基本子句。
提前感谢您的帮助。
-----------编辑--------
已重写 fetchSiblings 和 fetchPartners 代码,以使其更易于阅读:
public function fetchRelationships($id = 1, $generations = 5, $relationships = array())
{
$perId = $id;
if ($generations == 0) {
return $relationships;
} else {
$parents = $this->fetchParents($perId);
$relationships[$perId]['parents'] = $parents;
if (!empty($parents)) {
--$generations;
foreach ($parents as $parentRel) {
$perId = $parentRel->getPer2()->getId();
$relationships[$perId] = $this->fetchRelationships($perId, $generations, $relationships);
}
}
return $relationships;
}
}
【问题讨论】:
-
这五次可能是巧合,并非基于世代数。它将不得不多次调用“base”子句,因为它不是一个基础,它是一个尾巴。当你上树时,家庭就会分支。当世代 = 0 时,您处于伟大、伟大、曾祖父母的位置。而且你有不止 1 个!
-
是的,但我不知道如何解决它。我绝对不希望它在“整棵树完成”之外的任何条件下击中基本子句。我一直在关注广度,但我不确定它是否适用于此。
-
它必须多次击中它。没关系。您遇到了更大的问题,因为您只创建了一个数组,然后该数组具有引用主数组的条目。
-
感谢您的回复。我知道我编写代码的方式意味着它会不止一次地碰到子句,这就是我需要帮助的问题。传递数组以便它可以填充来自后代的数据,这不是我的主要问题。我不相信这是一个问题。如果我的递归是向后的,我认为是,那么我希望有人能够帮助我实现这一点。
-
当您迭代父关系时,您会修改
$perId... 这似乎很奇怪,因为在下一次迭代中,您似乎会查询父级的兄弟姐妹是它自己的父级 = S
标签: php recursion breadth-first-search