How to Output Array from Recursive PHP 7 Function without Array to String 错误

How to Output Array from Recursive PHP 7 Function without Array to String Error

我研究了几个看起来不错的 Stack Overflow 帖子,但没有为我提供解决问题的方法。我用 PHP 7 创建了一个 tree walker 函数,它递归地循环遍历所有节点,直到它到达一片叶子。我相信击中“叶子”符合“停止条件”(?)

无论如何,函数 processTree() 接受三个参数:一个数组、一个起始深度级别,最后是一个选项数组,这实际上是我能想到的在每个深度级别收集输出的唯一方法。

这里基本上是函数应该做的事情。我将一个具有三个维度的关联数组传递给它。该数组由结构如下的圣经经文组成:

$verses['book_name']['chapter_num']['verse_num'] = $verse_text

演示 $verses 数组:

$verses['Jeremiah'][29][11] = 'For I know the thoughts that I think toward you, saith the LORD, thoughts of peace, and not of evil, to give you an expected end.';
$verses['John'][3][16] = 'For God so loved the world, that he gave his only begotten Son, that whosoever believeth in him should not perish, but have everlasting life.';
$verses['Romans'][8][28] = 'And we know that all things work together for good to them that love God, to them who are the called according to his purpose.';
$verses['John'][1][1] = "In the beginning was the Word, and the Word was with God, and the Word was God.";
$verses['John'][1][3] = "All things were made by him; and without him was not any thing made that was made.";

这是我的函数现在的样子:

函数:processTree():

function processTree($tree, $lev=0, $options=[]) {
   $markup = '';
   $out_arr = [];

   foreach ($tree as $branch => $twig) {

      // Debug
      // If twig is verse text
      if (!is_array($twig)) {
         echo '<p><strong>Twig:</strong> ' . $twig . '</p>';
      }
      
      $markup .= '<li>';
      $cur_depth = $lev+1;

      if (is_array($twig)) {
         // if node
         echo '<p><strong>Branch:</strong> ' . $branch . '</p>';
         $options[$cur_depth] = $branch;
         $markup .= "<h$cur_depth>" .$branch. "</h$cur_depth>" . processTree($twig, $cur_depth, $options);
      } else {
         // if leaf
         $options[$cur_depth] = $branch;
         $markup .= "<h$cur_depth>" .$branch. "</h$cur_depth>" . $twig;
      }
      
      $markup .= var_dump($options);
      $markup .= '</li>';
      
   
   } // /END foreach

   $markup = '<ul>' . $markup . '</ul>';
   $out_arr['markup'] = $markup;
   $out_arr['results'] = $options; 
   
   return $out_arr;
}

// Since default values are defined for args 2 and 3 they are not needed here
echo processTree($verses);

当我输出一个字符串($markup)时,该函数有点工作,但是当我试图将它更改为输出数组时,它给我“Array to String conversion error”。我怀疑它与“if (is_array($twig))”部分中的 processTree() 调用有关,但我不确定如何解决它。

期望的输出:

给定三个变量 $book_name、$chapter_num 和 $verse_num 我应该能够 get/set 或者 $verse_text;这有效。但是,当我按顺序循环遍历数组时,我无法存储此信息。想象一下,我不知道数组中包含的所有经文是什么。我想遍历数组树,最后打印如下内容:

$result = processTree($verses);
var_dump($result);

// Output:
// Here are the rows/verses stored in array $verses:

Jeremiah 29:11
John 1:1
John 1:3
John 3:16
Romans 8:28

在函数中,我能够存储三个单独的值来构建该字符串列表,但我似乎无法弄清楚如何将它们构建成字符串,并防止这三个值覆盖前三个值。我认为问题在于维护状态(或“有状态”?)。 正在寻找解决这个问题的最优雅的方法。我希望这是有道理的,如果没有,请提问,我会尽力澄清。

资源:

以下是我在发布前研究过的 URLS:

在最后一行,您是 returning 空数组,您要将其附加到递归调用中。您应该使函数 return 无效,return 整个文本或单独调用该函数,因为它正在回显文本本身而不是将其作为文本附加。

//编辑:像这样:

function processTree($tree, $lev=0, $options=[]) {
   $markup = '';
   $out_arr = [];

   foreach ($tree as $branch => $twig) {

      // Debug
      // If twig is verse text
      if (!is_array($twig)) {
         echo '<p><strong>Twig:</strong> ' . $twig . '</p>';
      }
      
      $markup .= '<li>';
      $cur_depth = $lev+1;

      if (is_array($twig)) {
         // if node
         echo '<p><strong>Branch:</strong> ' . $branch . '</p>';
         $options[$cur_depth] = $branch;
         $markup .= "<h$cur_depth>" .$branch. "</h$cur_depth>" . processTree($twig, $cur_depth, $options);
      } else {
         // if leaf
         $options[$cur_depth] = $branch;
         $markup .= "<h$cur_depth>" .$branch. "</h$cur_depth>" . $twig;
      }
      
      $markup .= var_dump($options);
      $markup .= '</li>';
      
   
   } // /END foreach

   $markup = '<ul>' . $markup . '</ul>';
}

// Since default values are defined for args 2 and 3 they are not needed here
processTree($verses);

我不确定我是否正确理解了你的问题,但如果你知道你的数组只有三个维度,那么你不需要递归,只需要嵌套迭代:

foreach ($data as $book => $chapters) {
    foreach ($chapters as $chapter => $verses) {
        foreach ($verses as $verse => $text) {
            printf("%s %d:%d\n", $book, $chapter, $verse);
        }
    }
}

输出:

Jeremiah 29:11
John 3:16
John 1:1
John 1:3
Romans 8:28

如果你想把它作为一个数组:

$list = [];
foreach ($data as $book => $chapters) {
    foreach ($chapters as $chapter => $verses) {
        foreach ($verses as $verse => $text) {
            $list[] = sprintf('%s %d:%d', $book, $chapter, $verse);
        }
    }
}
print_r($list);

输出:

Array
(
    [0] => Jeremiah 29:11
    [1] => John 3:16
    [2] => John 1:1
    [3] => John 1:3
    [4] => Romans 8:28
)