从多维数组创建嵌套列表

时间:2023-01-02 21:17:42

I have an array in PHP, which looks like this:

我有一个PHP数组,看起来像这样:

array (
    [0] => array (
        [id] => 1
        [title] => "Title 1"
        [parent_id] => NULL
        [depth] => 0
    )
    [1] => array (
        [id] => 2
        [title] => "Title 2"
        [parent_id] => NULL
        [depth] => 0
    )
    [2] => array (
        [id] => 3
        [title] => "Title 3"
        [parent_id] => 2
        [depth] => 1
    )
    [3] => array (
        [id] => 4
        [title] => "Title 4"
        [parent_id] => 2
        [depth] => 1
    )
    [4] => array (
        [id] => 5
        [title] => "Title 5"
        [parent_id] => NULL
        [depth] => 0
    )
    [5] => array (
        [id] => 6
        [title] => "Title 6"
        [parent_id] => 4
        [depth] => 2
    )
)

What i want to do is iterate over this array and create a nested <ol> list from it. So the result should look like this:

我想要做的是迭代这个数组并从中创建一个嵌套的

    列表。所以结果应该是这样的:

<ol>
    <li>Title 1</li> // id = 1
    <li>Title 2</li> // id = 2
    <ol>
        <li>Title 3</li> // id = 3 -> parent_id = 2
        <li>Title 4</li> // id = 4 -> parent_id = 2
        <ol>
            <li>Title 6</li> // id = 6 -> parent_id = 4
        </ol>
    </ol>
    <li>Title 5</li> // id = 5
</ol>

I've been trying to think of a way how i could get this done. But so far every attempt failed...

我一直试图想办法如何完成这项工作。但到目前为止每次尝试都失败了

Anyone any idea how i can create such a nested <ol> list from an array like that?

任何人都知道如何从这样的数组创建这样一个嵌套的

    列表?

Please note that i do not have any control on the given data. I simply make a call to an API and it returns json data, which i convert to an array. And the array looks exactly like the one i described.

请注意,我对给定数据没有任何控制权。我只是调用一个API,它返回json数据,我将其转换为数组。阵列看起来与我描述的完全一样。

3 个解决方案

#1


13  

You should use recursion:

你应该使用递归:

First the array in 'php' syntax:

首先是'php'语法中的数组:

<?php
$a=array (
    '0' => array (
        'id' => 1,
        'title' => "Title 1",
        'parent_id' => 'NULL',
        'depth' => 0
    ),
    '1' => array (
        'id' => 2,
        'title' => "Title 2",
        'parent_id' => 'NULL',
        'depth' => 0
    ),
    '2' => array (
        'id' => 3,
        'title' => "Title 3",
        'parent_id' => 2,
        'depth' => 1
    ),
    '3' => array (
        'id' => 4,
        'title' => "Title 4",
        'parent_id' => 2,
        'depth' => 1
    ),
    '4' => array (
        'id' => 5,
        'title' => "Title 5",
        'parent_id' => 'NULL',
        'depth' => 0
    ),
    '5' => array (
        'id' => 6,
        'title' => "Title 6",
        'parent_id' => 4,
        'depth' => 0
    )
);

Here the code:

这里的代码:

$level = 'NULL';

function r( $a, $level) {
   $r = "<ol>";
   foreach ( $a as $i ) {
       if ($i['parent_id'] == $level ) {
          $r = $r . "<li>" . $i['title'] . r( $a, $i['id'] ) . "</li>";
       }
   }
   $r = $r . "</ol>";
   return $r;
}

print r( $a, $level );

?>

The results:

结果:

<ol><li>Title 1<ol></ol></li><li>Title 2<ol><li>Title 3<ol>
</ol></li><li>Title 4<ol><li>Title 6<ol></ol></li></ol></li></ol></li><li>Title 5
<ol></ol></li></ol>
  1. Title 1\n
    1. 标题1 \ n
    2. Title 2\n
      1. Title 3\n
        1. 标题3 \ n
        2. Title 4\n
          1. Title 6\n
            1. 标题6 \ n
          2. 标题4 \ n标题6 \ n
        3. 标题2 \ n标题3 \ n标题4 \ n标题6 \ n
        4. Title 5\n
          1. 标题5 \ n

          EDITED AFTER CHECK AS SOLUTION

          检查后作为解决方案编辑

          To avoid empty leafs:

          为了避免空叶:

          function r( $a, $level) {
             $r = '' ;
             foreach ( $a as $i ) {
                 if ($i['parent_id'] == $level ) {
                    $r = $r . "<li>" . $i['title'] . r( $a, $i['id'] ) . "</li>";
                 }
             }
             return ($r==''?'':"<ol>". $r . "</ol>");
          }
          

          #2


          4  

          You can try the following

          您可以尝试以下方法

          $array = array (
              "0" => array (
                  "id" => 1,
                  "title" => "Title 1",
                  "parent_id" => NULL,
                  "depth" => 0
              ),
              "1" => array (
                  "id" => 2,
                  "title" => "Title 2",
                  "parent_id" => NULL,
                  "depth" => 0
              ),
              "2" => array (
                  "id" => 3,
                  "title" => "Title 3",
                  "parent_id" => 2,
                  "depth" => 1
              ),
              "3" => array (
                  "id" => 4,
                  "title" => "Title 4",
                  "parent_id" => 2,
                  "depth" => 1
              ),
              "4" => array (
                  "id" => 5,
                  "title" => "Title 5",
                  "parent_id" => NULL,
                  "depth" => 0
              ),
              "5" => array (
                  "id" => 6,
                  "title" => "Title 6",
                  "parent_id" => 4,
                  "depth" => 0
              )
          );
          
          echo(make($array));
          

          Output

          产量

          <ol>
              <li>Title 1</li>
              <li>Title 2</li>
              <ol>
                  <li>Title 3</li>
                  <li>Title 4</li>
                  <ol>
                      <li>Title 6</li>
                  </ol>
              </ol>
              <li>Title 5</li>
          </ol>
          

          Function Used

          使用的功能

          function make(array $array, $no = 0) {
              $child = hasChildren($array, $no);
              if (empty($child))
                  return "";
              $content = "<ol>\n";
              foreach ( $child as $value ) {
                  $content .= sprintf("\t<li>%s</li>\n", $value['title']);
                  $content .= make($array, $value['id']);
              }
              $content .= "</ol>\n";
              return $content;
          }
          
          function hasChildren($array, $id) {
              return array_filter($array, function ($var) use($id) {
                  return $var['parent_id'] == $id;
              });
          }
          

          See Live Demo

          观看现场演示

          #3


          1  

          The following array:

          以下数组:

          Array
          (
              [0] => Content
              [1] => Array
                  (
                      [0] => International
                      [1] => Array
                          (
                              [0] => Mexico
                              [1] => Array
                                  (
                                      [0] => Tamaulipas
                                  )
          
                              [2] => USA
                          )
          
                  )
          
          )
          

          With this function:

          有了这个功能:

          function r($element) {
              foreach ($element as $value) {
                  if (!is_array($value)) {
                      echo "<li>";
                      echo $value;
                  } else {
                      echo "<ul>";
                      r($value);
                      echo "</li>";
                      echo "</ul>";
                  }
              }
          }
          

          PHP code:

          PHP代码:

          echo "<ul>";
          r($array);
          echo "</ul>";
          

          Returns:

          返回:

          <ul>
              <li>Public</li>
              <li>User</li>
              <li>Content
                  <ul>
                      <li>International
                          <ul>
                              <li>Mexico
                                  <ul>
                                      <li>Tamaulipas</li>
                                  </ul>  
                              </li>
                              <li>USA</li>
                          </ul>
                      </li>
                  </ul>
              </li>
          </ul>
          

          #1


          13  

          You should use recursion:

          你应该使用递归:

          First the array in 'php' syntax:

          首先是'php'语法中的数组:

          <?php
          $a=array (
              '0' => array (
                  'id' => 1,
                  'title' => "Title 1",
                  'parent_id' => 'NULL',
                  'depth' => 0
              ),
              '1' => array (
                  'id' => 2,
                  'title' => "Title 2",
                  'parent_id' => 'NULL',
                  'depth' => 0
              ),
              '2' => array (
                  'id' => 3,
                  'title' => "Title 3",
                  'parent_id' => 2,
                  'depth' => 1
              ),
              '3' => array (
                  'id' => 4,
                  'title' => "Title 4",
                  'parent_id' => 2,
                  'depth' => 1
              ),
              '4' => array (
                  'id' => 5,
                  'title' => "Title 5",
                  'parent_id' => 'NULL',
                  'depth' => 0
              ),
              '5' => array (
                  'id' => 6,
                  'title' => "Title 6",
                  'parent_id' => 4,
                  'depth' => 0
              )
          );
          

          Here the code:

          这里的代码:

          $level = 'NULL';
          
          function r( $a, $level) {
             $r = "<ol>";
             foreach ( $a as $i ) {
                 if ($i['parent_id'] == $level ) {
                    $r = $r . "<li>" . $i['title'] . r( $a, $i['id'] ) . "</li>";
                 }
             }
             $r = $r . "</ol>";
             return $r;
          }
          
          print r( $a, $level );
          
          ?>
          

          The results:

          结果:

          <ol><li>Title 1<ol></ol></li><li>Title 2<ol><li>Title 3<ol>
          </ol></li><li>Title 4<ol><li>Title 6<ol></ol></li></ol></li></ol></li><li>Title 5
          <ol></ol></li></ol>
          
          1. Title 1\n
            1. 标题1 \ n
            2. Title 2\n
              1. Title 3\n
                1. 标题3 \ n
                2. Title 4\n
                  1. Title 6\n
                    1. 标题6 \ n
                  2. 标题4 \ n标题6 \ n
                3. 标题2 \ n标题3 \ n标题4 \ n标题6 \ n
                4. Title 5\n
                  1. 标题5 \ n

                  EDITED AFTER CHECK AS SOLUTION

                  检查后作为解决方案编辑

                  To avoid empty leafs:

                  为了避免空叶:

                  function r( $a, $level) {
                     $r = '' ;
                     foreach ( $a as $i ) {
                         if ($i['parent_id'] == $level ) {
                            $r = $r . "<li>" . $i['title'] . r( $a, $i['id'] ) . "</li>";
                         }
                     }
                     return ($r==''?'':"<ol>". $r . "</ol>");
                  }
                  

                  #2


                  4  

                  You can try the following

                  您可以尝试以下方法

                  $array = array (
                      "0" => array (
                          "id" => 1,
                          "title" => "Title 1",
                          "parent_id" => NULL,
                          "depth" => 0
                      ),
                      "1" => array (
                          "id" => 2,
                          "title" => "Title 2",
                          "parent_id" => NULL,
                          "depth" => 0
                      ),
                      "2" => array (
                          "id" => 3,
                          "title" => "Title 3",
                          "parent_id" => 2,
                          "depth" => 1
                      ),
                      "3" => array (
                          "id" => 4,
                          "title" => "Title 4",
                          "parent_id" => 2,
                          "depth" => 1
                      ),
                      "4" => array (
                          "id" => 5,
                          "title" => "Title 5",
                          "parent_id" => NULL,
                          "depth" => 0
                      ),
                      "5" => array (
                          "id" => 6,
                          "title" => "Title 6",
                          "parent_id" => 4,
                          "depth" => 0
                      )
                  );
                  
                  echo(make($array));
                  

                  Output

                  产量

                  <ol>
                      <li>Title 1</li>
                      <li>Title 2</li>
                      <ol>
                          <li>Title 3</li>
                          <li>Title 4</li>
                          <ol>
                              <li>Title 6</li>
                          </ol>
                      </ol>
                      <li>Title 5</li>
                  </ol>
                  

                  Function Used

                  使用的功能

                  function make(array $array, $no = 0) {
                      $child = hasChildren($array, $no);
                      if (empty($child))
                          return "";
                      $content = "<ol>\n";
                      foreach ( $child as $value ) {
                          $content .= sprintf("\t<li>%s</li>\n", $value['title']);
                          $content .= make($array, $value['id']);
                      }
                      $content .= "</ol>\n";
                      return $content;
                  }
                  
                  function hasChildren($array, $id) {
                      return array_filter($array, function ($var) use($id) {
                          return $var['parent_id'] == $id;
                      });
                  }
                  

                  See Live Demo

                  观看现场演示

                  #3


                  1  

                  The following array:

                  以下数组:

                  Array
                  (
                      [0] => Content
                      [1] => Array
                          (
                              [0] => International
                              [1] => Array
                                  (
                                      [0] => Mexico
                                      [1] => Array
                                          (
                                              [0] => Tamaulipas
                                          )
                  
                                      [2] => USA
                                  )
                  
                          )
                  
                  )
                  

                  With this function:

                  有了这个功能:

                  function r($element) {
                      foreach ($element as $value) {
                          if (!is_array($value)) {
                              echo "<li>";
                              echo $value;
                          } else {
                              echo "<ul>";
                              r($value);
                              echo "</li>";
                              echo "</ul>";
                          }
                      }
                  }
                  

                  PHP code:

                  PHP代码:

                  echo "<ul>";
                  r($array);
                  echo "</ul>";
                  

                  Returns:

                  返回:

                  <ul>
                      <li>Public</li>
                      <li>User</li>
                      <li>Content
                          <ul>
                              <li>International
                                  <ul>
                                      <li>Mexico
                                          <ul>
                                              <li>Tamaulipas</li>
                                          </ul>  
                                      </li>
                                      <li>USA</li>
                                  </ul>
                              </li>
                          </ul>
                      </li>
                  </ul>