2016-05-27 3 views
1

У меня есть приложение для генеалогического древа в laravel, и я хочу, чтобы у вас было представление о плане (начинайте с семьи с давних времен, показывайте своим детям, показывайте семьи этих детей, дети этих семей и т. д.).Рекурсивная функция php: проблема с обнаружением ошибки

Так что я сделал эту рекурсивную функцию 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" 
    ] 
] 

Может ли кто-нибудь увидеть, где моя ошибка?

+0

Thanks Ryan- да, хорошая идея дать возможность проверить его! Сейчас все в базе данных ... Я не уверен, что вы имеете в виду для создания исходного массива PHP, но если вы знаете учебную страницу, я рад это сделать. –

+1

Annnnd Я только что нашел проблему: все отлично, если я просто верну эту $$ this_array и оставьте общий $ results_array. Теперь я вижу, что сообщение «найти ошибку» - это страшная идея, если нет простого способа изгнать людей из-за путаницы или потраченного впустую времени. –

+0

Рад, что вы исправили это :) –

ответ

0

Выглядит излишне сложным с динамическими массивами, и вы продолжаете заполнять один и тот же массив, поэтому 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" 
      ] 
     ] 
    ] 
] 
+0

спасибо, @gingerCodeNinja! Я думаю о том, как это может сработать ... часть, из-за которой мой мозг взрывается, заключается в том, что мое семейное дерево возвращается на 7 поколений, поэтому мне нужно, чтобы внутри «подсемейств» можно было идти глубже и глубже - я «Не совсем понятно, как я смогу подключить их внутри« подсемейств ».... не могли бы вы сказать больше? PS-Я сделал одно упрощение в приведенном выше коде, что приводит к моему результату в один массив, просто с дополнительным треском в середине –

1

Update: оказывается, что это работает, если я избавлюсь от этого последнего 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; 
    }