【问题标题】:recursive php function: trouble spotting the bug递归php函数:发现错误的麻烦
【发布时间】:2016-05-27 11:46:01
【问题描述】:

我在 laravel 中有一个家谱应用程序,我希望能够显示大纲视图(从很久以前的家庭开始,显示其孩子,显示那些孩子的家庭,那些家庭的孩子等)。

所以我做了这个递归 get_descendants 函数:

public static function get_descendants(Family $family, $results_array, $counter)
        {
            // start new round with a different temp array, to keep track
            $counter++;
            $this_array = "array_$counter";
            $$this_array = [];

            array_push ($$this_array, $family->caption);

            $kids = FamilyController::get_kids_of_family($family);

            // if family has no kids, return 0;
            if (!count($kids))
            {
                return 0;
            }

            else // add kids and check for their families
            {
                foreach ($kids as $kid) {
                    array_push ($$this_array, $kid->firstname);

                    // get families made by kid- for each one, call get_descendants
                    $families_made = FamilyController::get_families_person_made($kid);

                    foreach ($families_made as $new_family) {
                        array_push($$this_array, self::get_descendants($new_family, $$this_array, $counter));
                    }
                };

                // we've gone through the kids, add this round's array to the general results array
                array_push ($results_array, $$this_array);
            }
            return $results_array; 
        }

我已经通过打印语句确认循环是正确的,但是我保存结果的方式存在问题。我想要这样的东西,顶级家庭展示一次,孩子和他们的家庭嵌套:

array:1 [▼
  0 => array:4 [▼
    0 => "Padme & Anakin"
    1 => "Leia"
    2 => array:3 [▼
      0 => "Leia & Han"
      1 => "Kylo Ren"
    ]
    3 => "Luke"
  ]
]

但我得到了这个(中间有一个额外的重复):

array:1 [▼
  0 => array:4 [▼
    0 => "Padme & Anakin"
    1 => "Leia"
    2 => array:3 [▼
      0 => "Padme & Anakin"
      1 => "Leia"
      2 => array:3 [▼
        0 => "Leia & Han"
        1 => "Kylo Ren"
      ]
    ]
    3 => "Luke"
  ]
]

谁能看出我的错误在哪里?

【问题讨论】:

  • 感谢 Ryan- 是的,提供测试方法的好主意!现在一切都在数据库中...我不确定您对制作 PHP 源数组是什么意思,但如果您知道教程页面,我很乐意这样做。
  • Annnnd 我刚刚发现了问题:如果我只返回 $$this_array 并忽略一般的 $results_array,一切都很好。我现在看到“查找错误”帖子是一个糟糕的主意,没有更简单的方法让人们深挖遗憾 - 为混乱或浪费时间感到抱歉
  • 很高兴你修好了 :)

标签: php recursion


【解决方案1】:

更新:事实证明,如果我摆脱最终的 results_array 并完全使用动态数组,它就可以工作,如下所示:

    public static function get_descendants(Family $family, $results_array, $counter)
    {
        // start new round with a different temp array, to keep track
        $counter++;
        $this_array = "array_$counter";
        $$this_array = [];

        array_push ($$this_array, $family->caption);

        $kids = FamilyController::get_kids_of_family($family);

        // if family has no kids, return 0;
        if (!count($kids))
        {
            return 0;
        }

        else // add kids and check for their families
        {
            foreach ($kids as $kid) {
                array_push ($$this_array, $kid->first);

                // get families made by kid- for each one, call get_descendants
                $families_made = FamilyController::get_families_person_made($kid);

                if (count($families_made))
                {
                    foreach ($families_made as $new_family) {

                        array_push($$this_array, self::get_descendants($new_family, $$this_array, $counter));
                    }
                }

            };

        }
        return $$this_array;
    }

【讨论】:

    【解决方案2】:

    使用动态数组看起来不必要的复杂,而且你不断填充相同的数组,所以这就是 Luke 出现在错误位置的原因。

    更简洁的解决方案可能是非常具体地确定人们在数组中的位置,而不是使用动态数组名称。只是一个建议-

    public static function getDescendants(Family $family)
    {
        $family = [];
        $family['name'] = $family->caption;
        if ($kids = static::getKidsOfFamily($family)) {
            foreach ($kids as $kid) {
                $family['children'][] = $kid->firstname;
                $subfamilies = static::getFamiliesPersonMade($kid);
                foreach ($subfamilies as $subfamily) {
                    $family['subfamilies'][] = static::getDescendants($subfamily);
                }
            };
        }
    
        return $family; 
    }
    

    会产生类似的东西

    array [
        "name" => "Padme & Anakin"
        "children" => array [
            "Leia",
            "Luke"
        ],
        "subfamilies" => array [
            array [
                "name" => "Leia & Han"
                "children" => array [
                    "Kylo Re"
                ]
            ]
        ]
    ]
    

    【讨论】:

    • 谢谢,@gingerCodeNinja!我在想这怎么能起作用……让我的大脑爆炸的部分是我的家谱可以追溯到 7 代之前,所以我需要在“亚家族”中找到一种方法,以便能够继续深入下去——我我不太清楚如何将它们连接到“子家族”中......你能说更多吗? PS-我在上面的代码中做了一个简化,将我的结果放到一个数组中,只是中间有多余的东西
    猜你喜欢
    • 1970-01-01
    • 2021-02-12
    • 2013-10-30
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多