1

、などの親子 ID でそれ自体を参照する配列に格納されたデータ セットがあります id。最上位層には があり、無数の親子関係が存在する可能性があります。parent_idtitleparent_id0

そのため、再帰関数内のループを使用してこの配列を並べ替えて、foreach各配列要素をその親要素に対してチェックしていますが、このメソッドを長時間見つめていたと思います。

最終的には正しい順序で要素が配置されますが、リストを正しくネストできないように見えるため、この方法は実際には機能しないと思います。

  • これが最善のルートですか?
  • この方法を改善および修正するにはどうすればよいですか
  • 適用できる別のトリックはありますか?

ここに私の情報源があります:

<div>
    <div>Subpages</div>

    <ul>
    <?php subPages($this->subpages->toArray(), 0) ?>
    </ul>
    <br>
    <a href="javascript:;" onclick="">Add New Subpage</a>
</div>

<?php
    function subPages($subpages, $parent){

        foreach($subpages as $key => &$page){

            $newParent =  $page['id'];

            //If the current page is the parrent start a new list
            if($page['id'] == $parent)
            {
                //Echo out a new list
                echo '<ul>';
                echo '<li class="collapsed">';
                echo '<a href="javascript:;" class="toggle">+</a>';
                echo '<a href="javascript:;" onclick="">'.$page['title'].'</a>';        

                subPages($subpages, $newParent);

                echo '</li>';
                echo '</ul>';
            }
            //If the page's parent id matches the parent provided
            else if($page['parent_id'] == $parent)
            {
                //Echo out the link
                echo '<li class="collapsed">';
                echo '<a href="javascript:;" class="toggle">+</a>';
                echo '<a href="javascript:;" onclick="">'.$page['title'].'</a>';

                //Set the page as the new parent
                $newParent = $page['id'];

                //Remove page from array
                unset($subpages[$key]);

                //Check the rest of the array for children
                subPages($subpages, $newParent);

                echo '</li>';
            }
        }
    }
?>

いつものように、どんな支援も大歓迎です。何か不明な点があればお知らせください。

4

2 に答える 2

2

皆さんがまだこれに対する本当の答えを探しているとは思えませんが、同じ問題を抱えている他の人を助けるかもしれません. 以下は、親の下に子を配置する配列を再帰化する再帰関数です。

$initial = array(
    array(
        'name' => 'People',
        'ID' => 2,
        'parent' => 0
        ),
    array(
        'name' => 'Paul',
        'ID' => 4,
        'parent' => 2
        ),
    array(
        'name' => 'Liz',
        'ID' => 5,
        'parent' => 2
        ),
    array(
        'name' => 'Comus',
        'ID' => 6,
        'parent' => 3
        ),
    array(
        'name' => 'Mai',
        'ID' => 7,
        'parent' => 2
        ),
    array(
        'name' => 'Titus',
        'ID' => 8,
        'parent' => 3
        ),
    array(
        'name' => 'Adult',
        'ID' => 9,
        'parent' => 6
        ),
    array(
        'name' => 'Puppy',
        'ID' => 10,
        'parent' => 8
        ),
    array(
        'name' => 'Programmers',
        'ID' => 11,
        'parent' => 4
        )   ,
    array(
        'name' => 'Animals',
        'ID' => 3,
        'parent' => 0
        )                           
    );


/*---------------------------------
function parentChildSort_r
$idField        = The item's ID identifier (required)
$parentField    = The item's parent identifier (required)
$els            = The array (required)
$parentID       = The parent ID for which to sort (internal)
$result     = The result set (internal)
$depth          = The depth (internal)
----------------------------------*/

function parentChildSort_r($idField, $parentField, $els, $parentID = 0, &$result = array(), &$depth = 0){
    foreach ($els as $key => $value):
        if ($value[$parentField] == $parentID){
            $value['depth'] = $depth;
            array_push($result, $value);
            unset($els[$key]);
            $oldParent = $parentID; 
            $parentID = $value[$idField];
            $depth++;
            parentChildSort_r($idField,$parentField, $els, $parentID, $result, $depth);
            $parentID = $oldParent;
            $depth--;
        }
    endforeach;
    return $result;
}

$result = parentChildSort_r('ID','parent',$initial);

print '<pre>';
print_r($result);
print '</pre>';

これは、元の配列から要素を削除し、適切な順序で結果セットに配置する緩やかな方法です。やや一般的なものにしたので、「ID」フィールドと「親」フィールドの名前を指定するだけで済みます。トップ レベルのアイテムは、parent_id (名前は何でも構いません) が 0 である必要があります。また、各アイテムに深度マーカーを追加して、出力時にフォーマットできるようにします。

于 2013-05-25T19:24:00.667 に答える
0

私はあなたを助けようとします。

このような関係を 1 回のパスで構成することが可能です。

    /**
     * Used for "recursive" folding of layout items
     * Algorithm of infinite tree (non recursive method)
     * 
     * @param array $items
     * @return array
     */
    function _foldItems($items) {

        $result = array();

        foreach ($items as $key => $item) {

            $itemName = $item['name'];

            if (!isset($item['parent']))
                continue;
            else {

                $parentName = $item['parent']; // it can be either `name` or some `id` of the parent item

                if (isset($result[$itemName][$item['sequence']])) {

                    // Done to eliminate `Warning: Cannot use a scalar value as an array in atLeisure_PropertyImport.class.php`
                    // Sometimes elements already in the list and have [name] => $count and next line tries to put item in array (item becomes parent)
                    if (    isset($result[$parentName][$item['parentSequence']]['items'][$itemName]) AND
                            is_scalar($result[$parentName][$item['parentSequence']]['items'][$itemName])
                        )
                        $result[$parentName][$item['parentSequence']]['items'][$itemName] = array();

                    $result[$parentName][$item['parentSequence']]['items'][$itemName][$item['sequence']] = $result[$itemName][$item['sequence']];

                    unset($result[$itemName][$item['sequence']]);
                } else
                    $result[$parentName][$item['parentSequence']]['items'][$itemName] = $item['count'];

                unset($items[$key]);

                } // if //

            if (empty($result[$itemName]))
                unset($result[$itemName]);

        } // foreach //

        foreach ($items as $item) { // enumerating rest of the items (single items)
            $itemName = $item['itemName'];

            if (!isset($result[$itemName]))
                $result[$itemName][$item['sequence']] = $item['count'];
        }

        return $result;

    }

コードが多すぎるため、例を読んだり理解したりするのは少し難しいかもしれませんが、私はこの関数を 1 つのプロジェクトのために少し前に作成しましたが、うまく機能しているようです。

注: 1 つの親アイテムに複数の同じアイテムがリンクされている場合にも機能します。アイテムのシーケンス番号を使用して、同様の値を 1 つにエイリアス化することを回避します。

于 2012-08-16T15:32:27.320 に答える