11

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
    )
)

私がやりたいことは、この配列を反復処理し、<ol>そこからネストされたリストを作成することです。したがって、結果は次のようになります。

<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>

どうすればこれを実現できるかを考えてみました。しかし、これまでのところ、すべての試みは失敗しています...

そのような配列からそのようなネストされた<ol>リストを作成する方法を知っている人はいますか?

私は与えられたデータを制御できないことに注意してください。API を呼び出すだけで、配列に変換する json データが返されます。そして、配列は私が説明したものとまったく同じように見えます。

4

3 に答える 3

15

再帰を使用する必要があります:

最初に「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
    )
);

ここにコード

$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 );

?>

結果: _

<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. タイトル 1\n
    1. タイトル 2\n
      1. タイトル 3\n
        1. タイトル 4\n
          1. タイトル 6\n
        2. タイトル 5\n

          解決策として確認後に編集

          空のリーフを回避するには:

          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>");
          }
          
          于 2012-10-07T19:06:19.233 に答える
          4

          以下を試すことができます

          $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));
          

          出力

          <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 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;
              });
          }
          

          ライブデモを見る

          于 2012-10-07T19:20:56.527 に答える